From 075092411e2df23ff9dd0123f16951f9363ab689 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 29 Mar 2017 21:28:15 +1030 Subject: [PATCH] lightningd/channel: generate htlc txs and wscripts as well. In practice, this is what we want, either to generate or check signatures. Signed-off-by: Rusty Russell --- lightningd/channel.c | 105 ++++++++++++++++++++++++--- lightningd/channel.h | 29 +++++--- lightningd/channel/channel.c | 12 ++-- lightningd/opening/opening.c | 106 +++++++++++---------------- lightningd/test/run-channel.c | 131 ++++++++++++++++++++++++++++------ 5 files changed, 274 insertions(+), 109 deletions(-) diff --git a/lightningd/channel.c b/lightningd/channel.c index 1ac05c4f5..220ee50b8 100644 --- a/lightningd/channel.c +++ b/lightningd/channel.c @@ -3,6 +3,8 @@ #include "type_to_string.h" #include #include +#include +#include #include #include #include @@ -10,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -110,6 +113,8 @@ struct channel *new_channel(const tal_t *ctx, const struct channel_config *remote, const struct basepoints *local_basepoints, const struct basepoints *remote_basepoints, + const struct pubkey *local_funding_pubkey, + const struct pubkey *remote_funding_pubkey, enum side funder) { struct channel *channel = tal(ctx, struct channel); @@ -126,6 +131,8 @@ struct channel *new_channel(const tal_t *ctx, channel->funder = funder; channel->config[LOCAL] = local; channel->config[REMOTE] = remote; + channel->funding_pubkey[LOCAL] = *local_funding_pubkey; + channel->funding_pubkey[REMOTE] = *remote_funding_pubkey; htlc_map_init(&channel->htlcs); channel->view[LOCAL].feerate_per_kw @@ -154,14 +161,78 @@ struct channel *new_channel(const tal_t *ctx, return channel; } -/* FIXME: We could cache this. */ -struct bitcoin_tx *channel_tx(const tal_t *ctx, - const struct channel *channel, - const struct pubkey *per_commitment_point, - const struct htlc ***htlcmap, - enum side side) +static void add_htlcs(struct bitcoin_tx ***txs, + const u8 ***wscripts, + const struct htlc **htlcmap, + const struct channel *channel, + const struct pubkey *side_payment_key, + const struct pubkey *other_payment_key, + const struct pubkey *side_revocation_key, + const struct pubkey *side_delayed_payment_key, + enum side side) { - struct bitcoin_tx *tx; + size_t i, n; + struct sha256_double txid; + u32 feerate_per_kw = channel->view[side].feerate_per_kw; + + /* Get txid of commitment transaction */ + bitcoin_txid((*txs)[0], &txid); + + for (i = 0; i < tal_count(htlcmap); i++) { + const struct htlc *htlc = htlcmap[i]; + struct bitcoin_tx *tx; + u8 *wscript; + + if (!htlc) + continue; + + if (htlc_owner(htlc) == side) { + tx = htlc_timeout_tx(*txs, &txid, i, + htlc, + to_self_delay(channel, side), + side_revocation_key, + side_delayed_payment_key, + feerate_per_kw); + wscript = bitcoin_wscript_htlc_offer(*wscripts, + side_payment_key, + other_payment_key, + &htlc->rhash, + side_revocation_key); + } else { + tx = htlc_success_tx(*txs, &txid, i, + htlc, + to_self_delay(channel, side), + side_revocation_key, + side_delayed_payment_key, + feerate_per_kw); + wscript = bitcoin_wscript_htlc_receive(*wscripts, + &htlc->expiry, + side_payment_key, + other_payment_key, + &htlc->rhash, + side_revocation_key); + } + + /* Append to array. */ + n = tal_count(*txs); + assert(n == tal_count(*wscripts)); + + tal_resize(wscripts, n+1); + tal_resize(txs, n+1); + (*wscripts)[n] = wscript; + (*txs)[n] = tx; + } +} + +/* FIXME: We could cache these. */ +struct bitcoin_tx **channel_txs(const tal_t *ctx, + const struct htlc ***htlcmap, + const u8 ***wscripts, + const struct channel *channel, + const struct pubkey *per_commitment_point, + enum side side) +{ + struct bitcoin_tx **txs; const struct htlc **committed; /* Payment keys for @side and !@side */ struct pubkey side_payment_key, other_payment_key; @@ -193,7 +264,12 @@ struct bitcoin_tx *channel_tx(const tal_t *ctx, /* Figure out what @side will already be committed to. */ gather_htlcs(ctx, channel, side, &committed, NULL, NULL); - tx = commit_tx(ctx, &channel->funding_txid, + /* NULL map only allowed at beginning, when we know no HTLCs */ + if (!htlcmap) + assert(tal_count(committed) == 0); + + txs = tal_arr(ctx, struct bitcoin_tx *, 1); + txs[0] = commit_tx(ctx, &channel->funding_txid, channel->funding_txout, channel->funding_msat / 1000, channel->funder, @@ -212,8 +288,19 @@ struct bitcoin_tx *channel_tx(const tal_t *ctx, ^ 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]); + + if (htlcmap) + add_htlcs(&txs, wscripts, *htlcmap, channel, + &side_payment_key, &other_payment_key, + &side_revocation_key, &side_delayed_payment_key, + side); + tal_free(committed); - return tx; + return txs; } struct channel *copy_channel(const tal_t *ctx, const struct channel *old) diff --git a/lightningd/channel.h b/lightningd/channel.h index 5cbde2c16..d40590c91 100644 --- a/lightningd/channel.h +++ b/lightningd/channel.h @@ -29,6 +29,9 @@ struct channel { struct sha256_double funding_txid; unsigned int funding_txout; + /* Keys used to spend funding tx. */ + struct pubkey funding_pubkey[NUM_SIDES]; + /* Millisatoshis in from commitment tx */ u64 funding_msat; @@ -126,6 +129,8 @@ static inline u16 to_self_delay(const struct channel *channel, enum side side) * @remote: remote channel configuration * @local_basepoints: local basepoints. * @remote_basepoints: remote basepoints. + * @local_fundingkey: local funding key + * @remote_fundingkey: remote funding key * @funder: which side initiated it. * * Returns state, or NULL if malformed. @@ -140,24 +145,30 @@ struct channel *new_channel(const tal_t *ctx, const struct channel_config *remote, const struct basepoints *local_basepoints, const struct basepoints *remote_basepoints, + const struct pubkey *local_funding_pubkey, + const struct pubkey *remote_funding_pubkey, enum side funder); + /** - * channel_tx: Get the current commitment transaction for the channel. + * channel_txs: Get the current commitment and htlc txs for the channel. * @ctx: tal context to allocate return value from. * @channel: The channel to evaluate - * @per_commitment_point: Per-commitment point to determine keys * @htlc_map: Pointer to htlcs for each tx output (allocated off @ctx) or NULL. + * @wscripts: Pointer to array of wscript for each tx returned (alloced off @ctx) + * @per_commitment_point: Per-commitment point to determine keys * @side: which side to get the commitment transaction for * * Returns the unsigned commitment transaction for the committed state - * for @side and fills in @htlc_map (if not NULL), or NULL on key - * derivation failure. + * for @side, followed by the htlc transactions in output order, and + * fills in @htlc_map (if not NULL), or NULL on key derivation + * failure. */ -struct bitcoin_tx *channel_tx(const tal_t *ctx, - const struct channel *channel, - const struct pubkey *per_commitment_point, - const struct htlc ***htlcmap, - enum side side); +struct bitcoin_tx **channel_txs(const tal_t *ctx, + const struct htlc ***htlcmap, + const u8 ***wscripts, + const struct channel *channel, + const struct pubkey *per_commitment_point, + enum side side); /** * actual_feerate: what is the actual feerate for the local side. diff --git a/lightningd/channel/channel.c b/lightningd/channel/channel.c index ada5aa80a..d74dee74d 100644 --- a/lightningd/channel/channel.c +++ b/lightningd/channel/channel.c @@ -43,7 +43,6 @@ struct peer { struct channel_config conf[NUM_SIDES]; struct pubkey next_per_commit[NUM_SIDES]; bool funding_locked[NUM_SIDES]; - struct pubkey funding_pubkey[NUM_SIDES]; /* Their sig for current commit. */ secp256k1_ecdsa_signature their_commit_sig; @@ -143,8 +142,8 @@ static void send_channel_announcement(struct peer *peer) &peer->announcement_bitcoin_sigs[first], &peer->announcement_bitcoin_sigs[second], &peer->short_channel_ids[LOCAL], &peer->node_ids[first], - &peer->node_ids[second], &peer->funding_pubkey[first], - &peer->funding_pubkey[second], features); + &peer->node_ids[second], &peer->channel->funding_pubkey[first], + &peer->channel->funding_pubkey[second], features); msg_enqueue(&peer->peer_out, cannounce); daemon_conn_send(&peer->gossip_client, take(cannounce)); @@ -232,6 +231,7 @@ static void init_channel(struct peer *peer, const u8 *msg) u32 feerate; u64 funding_satoshi, push_msat; u16 funding_txout; + struct pubkey funding_pubkey[NUM_SIDES]; struct sha256_double funding_txid; bool am_funder; @@ -240,7 +240,7 @@ static void init_channel(struct peer *peer, const u8 *msg) &peer->conf[LOCAL], &peer->conf[REMOTE], &peer->their_commit_sig, &peer->pcs.cs, - &peer->funding_pubkey[REMOTE], + &funding_pubkey[REMOTE], &points[REMOTE].revocation, &points[REMOTE].payment, &points[REMOTE].delayed_payment, @@ -254,7 +254,7 @@ static void init_channel(struct peer *peer, const u8 *msg) tal_hex(msg, msg)); /* We derive everything from the one secret seed. */ - derive_basepoints(&seed, &peer->funding_pubkey[LOCAL], &points[LOCAL], + derive_basepoints(&seed, &funding_pubkey[LOCAL], &points[LOCAL], &peer->our_secrets, &peer->shaseed, &peer->next_per_commit[LOCAL], 1); @@ -262,6 +262,8 @@ static void init_channel(struct peer *peer, const u8 *msg) funding_satoshi, push_msat, feerate, &peer->conf[LOCAL], &peer->conf[REMOTE], &points[LOCAL], &points[REMOTE], + &funding_pubkey[LOCAL], + &funding_pubkey[REMOTE], am_funder ? LOCAL : REMOTE); peer->channel_direction = get_channel_direction( diff --git a/lightningd/opening/opening.c b/lightningd/opening/opening.c index 1bc51a7ea..c2c30ef25 100644 --- a/lightningd/opening/opening.c +++ b/lightningd/opening/opening.c @@ -144,42 +144,6 @@ static void check_config_bounds(struct state *state, remoteconf->max_accepted_htlcs); } -static bool check_commit_sig(const struct state *state, - const struct pubkey *our_funding_key, - const struct pubkey *their_funding_key, - struct bitcoin_tx *tx, - const secp256k1_ecdsa_signature *remotesig) -{ - u8 *wscript; - bool ret; - - wscript = bitcoin_redeem_2of2(state, - our_funding_key, their_funding_key); - - ret = check_tx_sig(tx, 0, NULL, wscript, their_funding_key, remotesig); - tal_free(wscript); - return ret; -} - -static secp256k1_ecdsa_signature -sign_remote_commit(const struct state *state, - const struct pubkey *our_funding_key, - const struct pubkey *their_funding_key, - struct bitcoin_tx *tx) -{ - u8 *wscript; - secp256k1_ecdsa_signature sig; - - wscript = bitcoin_redeem_2of2(state, - our_funding_key, their_funding_key); - - /* Commit tx only has one input: funding tx. */ - sign_tx_input(tx, 0, NULL, wscript, &state->our_secrets.funding_privkey, - our_funding_key, &sig); - tal_free(wscript); - return sig; -} - /* We always set channel_reserve_satoshis to 1%, rounded up. */ static void set_reserve(u64 *reserve, u64 funding) { @@ -220,12 +184,14 @@ static u8 *open_channel(struct state *state, const struct basepoints *ours, u32 max_minimum_depth) { + const tal_t *tmpctx = tal_tmpctx(state); struct channel_id channel_id, id_in; u8 *msg; - struct bitcoin_tx *tx; + struct bitcoin_tx **txs; struct basepoints theirs; struct pubkey their_funding_pubkey; secp256k1_ecdsa_signature sig; + const u8 **wscripts; set_reserve(&state->localconf.channel_reserve_satoshis, state->funding_satoshis); @@ -249,7 +215,7 @@ static u8 *open_channel(struct state *state, "push-msat must be < %"PRIu64, 1000 * state->funding_satoshis); - msg = towire_open_channel(state, &genesis_blockhash.sha, &channel_id, + msg = towire_open_channel(tmpctx, &genesis_blockhash.sha, &channel_id, state->funding_satoshis, state->push_msat, state->localconf.dust_limit_satoshis, state->localconf.max_htlc_value_in_flight_msat, @@ -269,7 +235,7 @@ static u8 *open_channel(struct state *state, state->remoteconf = tal(state, struct channel_config); - msg = sync_crypto_read(state, &state->cs, PEER_FD); + msg = sync_crypto_read(tmpctx, &state->cs, PEER_FD); if (!msg) peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_READ_FAILED, "Reading accept_channel"); @@ -324,12 +290,12 @@ static u8 *open_channel(struct state *state, check_config_bounds(state, state->remoteconf); /* Now, ask master create a transaction to pay those two addresses. */ - msg = towire_opening_open_reply(state, our_funding_pubkey, + msg = towire_opening_open_reply(tmpctx, our_funding_pubkey, &their_funding_pubkey); wire_sync_write(REQ_FD, msg); /* Expect funding tx. */ - msg = wire_sync_read(state, REQ_FD); + msg = wire_sync_read(tmpctx, REQ_FD); if (!fromwire_opening_open_funding(msg, NULL, &state->funding_txid, &state->funding_txout)) @@ -347,6 +313,8 @@ static u8 *open_channel(struct state *state, &state->localconf, state->remoteconf, ours, &theirs, + our_funding_pubkey, + &their_funding_pubkey, LOCAL); if (!state->channel) peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_BAD_PARAM, @@ -360,17 +328,18 @@ static u8 *open_channel(struct state *state, * for the initial commitment transactions. After receiving the * peer's signature, it will broadcast the funding transaction. */ - tx = channel_tx(state, state->channel, - &state->next_per_commit[REMOTE], NULL, REMOTE); - sig = sign_remote_commit(state, - our_funding_pubkey, &their_funding_pubkey, - tx); + txs = channel_txs(tmpctx, NULL, &wscripts, state->channel, + &state->next_per_commit[REMOTE], REMOTE); + + sign_tx_input(txs[0], 0, NULL, wscripts[0], + &state->our_secrets.funding_privkey, + our_funding_pubkey, &sig); status_trace("signature %s on tx %s using key %s", type_to_string(trc, secp256k1_ecdsa_signature, &sig), - type_to_string(trc, struct bitcoin_tx, tx), + type_to_string(trc, struct bitcoin_tx, txs[0]), type_to_string(trc, struct pubkey, our_funding_pubkey)); - msg = towire_funding_created(state, &channel_id, + msg = towire_funding_created(tmpctx, &channel_id, &state->funding_txid.sha, state->funding_txout, &sig); @@ -386,7 +355,7 @@ static u8 *open_channel(struct state *state, * commitment transaction, so they can broadcast it knowing they can * redeem their funds if they need to. */ - msg = sync_crypto_read(state, &state->cs, PEER_FD); + msg = sync_crypto_read(tmpctx, &state->cs, PEER_FD); if (!msg) peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_READ_FAILED, "Reading funding_signed"); @@ -417,18 +386,21 @@ static u8 *open_channel(struct state *state, * * The recipient MUST fail the channel if `signature` is incorrect. */ - tx = channel_tx(state, state->channel, - &state->next_per_commit[LOCAL], NULL, LOCAL); + txs = channel_txs(tmpctx, NULL, &wscripts, state->channel, + &state->next_per_commit[LOCAL], LOCAL); - if (!check_commit_sig(state, our_funding_pubkey, - &their_funding_pubkey, tx, &sig)) + if (!check_tx_sig(txs[0], 0, NULL, wscripts[0], &their_funding_pubkey, + &sig)) { peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_READ_FAILED, "Bad signature %s on tx %s using key %s", type_to_string(trc, secp256k1_ecdsa_signature, &sig), - type_to_string(trc, struct bitcoin_tx, tx), + type_to_string(trc, struct bitcoin_tx, txs[0]), type_to_string(trc, struct pubkey, &their_funding_pubkey)); + } + + tal_free(tmpctx); /* BOLT #2: * @@ -456,9 +428,10 @@ static u8 *recv_channel(struct state *state, struct basepoints theirs; struct pubkey their_funding_pubkey; secp256k1_ecdsa_signature theirsig, sig; - struct bitcoin_tx *tx; + struct bitcoin_tx **txs; struct sha256_double chain_hash; u8 *msg; + const u8 **wscripts; state->remoteconf = tal(state, struct channel_config); @@ -590,6 +563,8 @@ static u8 *recv_channel(struct state *state, &state->localconf, state->remoteconf, ours, &theirs, + our_funding_pubkey, + &their_funding_pubkey, REMOTE); if (!state->channel) peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_BAD_PARAM, @@ -613,18 +588,19 @@ static u8 *recv_channel(struct state *state, * * The recipient MUST fail the channel if `signature` is incorrect. */ - tx = channel_tx(state, state->channel, - &state->next_per_commit[LOCAL], NULL, LOCAL); + txs = channel_txs(state, NULL, &wscripts, state->channel, + &state->next_per_commit[LOCAL], LOCAL); - if (!check_commit_sig(state, our_funding_pubkey, - &their_funding_pubkey, tx, &theirsig)) + if (!check_tx_sig(txs[0], 0, NULL, wscripts[0], &their_funding_pubkey, + &theirsig)) { peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_READ_FAILED, "Bad signature %s on tx %s using key %s", type_to_string(trc, secp256k1_ecdsa_signature, &theirsig), - type_to_string(trc, struct bitcoin_tx, tx), + type_to_string(trc, struct bitcoin_tx, txs[0]), type_to_string(trc, struct pubkey, &their_funding_pubkey)); + } /* BOLT #2: * @@ -645,11 +621,11 @@ static u8 *recv_channel(struct state *state, * commitment transaction, so they can broadcast it knowing they can * redeem their funds if they need to. */ - tx = channel_tx(state, state->channel, - &state->next_per_commit[REMOTE], NULL, REMOTE); - sig = sign_remote_commit(state, - our_funding_pubkey, &their_funding_pubkey, - tx); + txs = channel_txs(state, NULL, &wscripts, state->channel, + &state->next_per_commit[REMOTE], REMOTE); + sign_tx_input(txs[0], 0, NULL, wscripts[0], + &state->our_secrets.funding_privkey, + our_funding_pubkey, &sig); msg = towire_funding_signed(state, &channel_id, &sig); if (!sync_crypto_write(&state->cs, PEER_FD, msg)) diff --git a/lightningd/test/run-channel.c b/lightningd/test/run-channel.c index 3f296a6a6..97979f618 100644 --- a/lightningd/test/run-channel.c +++ b/lightningd/test/run-channel.c @@ -36,6 +36,11 @@ static struct sha256_double txid_from_hex(const char *hex) return sha256; } +static struct bitcoin_tx *tx_from_hex(const tal_t *ctx, const char *hex) +{ + return bitcoin_tx_from_hex(ctx, hex, strlen(hex)); +} + /* BOLT #3: * * local_feerate_per_kw: 0 @@ -99,7 +104,7 @@ static u64 feerates[] = { * htlc 4 expiry: 504 * htlc 4 payment_preimage: 0404040404040404040404040404040404040404040404040404040404040404 */ -static const struct htlc **add_htlcs(struct channel *channel, enum side side) +static const struct htlc **include_htlcs(struct channel *channel, enum side side) { int i; const struct htlc **htlcs = tal_arr(channel, const struct htlc *, 5); @@ -202,6 +207,18 @@ static void tx_must_be_eq(const struct bitcoin_tx *a, tal_free(tmpctx); } +static void txs_must_be_eq(struct bitcoin_tx **a, struct bitcoin_tx **b) +{ + size_t i; + + if (tal_count(a) != tal_count(b)) + errx(1, "A has %zu txs, B has %zu", + tal_count(a), tal_count(b)); + + for (i = 0; i < tal_count(a); i++) + tx_must_be_eq(a[i], b[i]); +} + static void send_and_fulfill_htlc(struct channel *channel, enum side sender, u64 msatoshi) @@ -255,16 +272,18 @@ int main(void) u64 funding_amount_satoshi, feerate_per_kw; unsigned int funding_output_index; struct pubkey localkey, remotekey; + struct pubkey local_funding_pubkey, remote_funding_pubkey; struct pubkey local_delayedkey; struct pubkey local_revocation_key; struct pubkey local_per_commitment_point; struct basepoints localbase, remotebase; struct pubkey *unknown = tal(tmpctx, struct pubkey); - struct bitcoin_tx *raw_tx, *tx; + struct bitcoin_tx *raw_tx, **txs, **txs2; struct channel_config *local_config = tal(tmpctx, struct channel_config); struct channel_config *remote_config = tal(tmpctx, struct channel_config); u64 to_local_msat, to_remote_msat; const struct htlc **htlc_map, **htlcs; + const u8 *funding_wscript, **wscripts; size_t i; secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY @@ -338,6 +357,20 @@ int main(void) localbase.revocation = *unknown; remotebase.delayed_payment = *unknown; + /* BOLT #3: + * + * local_funding_pubkey: 023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb + * remote_funding_pubkey: 030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c1 + */ + local_funding_pubkey = pubkey_from_hex("023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb"); + remote_funding_pubkey = pubkey_from_hex("030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c1"); + + /* BOLT #3: + * + * # funding wscript = 5221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae + */ + funding_wscript = tal_hexdata(tmpctx, "5221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae", strlen("5221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae")); + /* BOLT #3: * * name: simple commitment tx with no HTLCs @@ -355,6 +388,7 @@ int main(void) local_config, remote_config, &localbase, &remotebase, + &local_funding_pubkey, &remote_funding_pubkey, LOCAL); rchannel = new_channel(tmpctx, &funding_txid, funding_output_index, @@ -363,6 +397,7 @@ int main(void) remote_config, local_config, &remotebase, &localbase, + &remote_funding_pubkey, &local_funding_pubkey, REMOTE); /* BOLT #3: * @@ -400,13 +435,17 @@ int main(void) to_remote_msat, NULL, &htlc_map, 0x2bb038521914 ^ 42, LOCAL); - tx = channel_tx(tmpctx, lchannel, &local_per_commitment_point, - &htlc_map, LOCAL); - tx_must_be_eq(tx, raw_tx); + txs = channel_txs(tmpctx, &htlc_map, &wscripts, + lchannel, &local_per_commitment_point, LOCAL); + assert(tal_count(txs) == 1); + assert(tal_count(htlc_map) == 2); + assert(tal_count(wscripts) == 1); + assert(scripteq(wscripts[0], funding_wscript)); + tx_must_be_eq(txs[0], raw_tx); - tx = channel_tx(tmpctx, rchannel, &local_per_commitment_point, - &htlc_map, REMOTE); - tx_must_be_eq(tx, raw_tx); + txs2 = channel_txs(tmpctx, &htlc_map, &wscripts, + rchannel, &local_per_commitment_point, REMOTE); + txs_must_be_eq(txs, txs2); /* BOLT #3: * @@ -431,23 +470,73 @@ int main(void) assert(lchannel->view[REMOTE].owed_msat[REMOTE] == rchannel->view[LOCAL].owed_msat[LOCAL]); - raw_tx = channel_tx(tmpctx, lchannel, &local_per_commitment_point, - &htlc_map, LOCAL); - tx = channel_tx(tmpctx, rchannel, &local_per_commitment_point, - &htlc_map, REMOTE); - tx_must_be_eq(tx, raw_tx); + txs = channel_txs(tmpctx, &htlc_map, &wscripts, + lchannel, &local_per_commitment_point, LOCAL); + assert(tal_count(txs) == 1); + txs2 = channel_txs(tmpctx, &htlc_map, &wscripts, + rchannel, &local_per_commitment_point, REMOTE); + txs_must_be_eq(txs, txs2); /* FIXME: Adjust properly! */ lchannel->view[LOCAL].feerate_per_kw = feerate_per_kw; rchannel->view[REMOTE].feerate_per_kw = feerate_per_kw; - htlcs = add_htlcs(lchannel, LOCAL); - add_htlcs(rchannel, REMOTE); + htlcs = include_htlcs(lchannel, LOCAL); + include_htlcs(rchannel, REMOTE); assert(lchannel->view[LOCAL].owed_msat[LOCAL] == rchannel->view[REMOTE].owed_msat[REMOTE]); assert(lchannel->view[REMOTE].owed_msat[REMOTE] == rchannel->view[LOCAL].owed_msat[LOCAL]); + txs = channel_txs(tmpctx, &htlc_map, &wscripts, + lchannel, &local_per_commitment_point, LOCAL); + assert(tal_count(txs) == 6); + txs2 = channel_txs(tmpctx, &htlc_map, &wscripts, + rchannel, &local_per_commitment_point, REMOTE); + txs_must_be_eq(txs, txs2); + + /* FIXME: Compare signatures! */ + /* BOLT #3: + * + * output htlc_success_tx 0: 020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219700000000000000000001e8030000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402206a6e59f18764a5bf8d4fa45eebc591566689441229c918b480fb2af8cc6a4aeb02205248f273be447684b33e3c8d1d85a8e0ca9fa0bae9ae33f0527ada9c162919a60147304402207cb324fa0de88f452ffa9389678127ebcf4cabe1dd848b8e076c1a1962bf34720220116ed922b12311bd602d67e60d2529917f21c5b82f25ff6506c0f87886b4dfd5012000000000000000000000000000000000000000000000000000000000000000008a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc688527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f401b175ac686800000000 + */ + raw_tx = tx_from_hex(tmpctx, "020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219700000000000000000001e8030000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402206a6e59f18764a5bf8d4fa45eebc591566689441229c918b480fb2af8cc6a4aeb02205248f273be447684b33e3c8d1d85a8e0ca9fa0bae9ae33f0527ada9c162919a60147304402207cb324fa0de88f452ffa9389678127ebcf4cabe1dd848b8e076c1a1962bf34720220116ed922b12311bd602d67e60d2529917f21c5b82f25ff6506c0f87886b4dfd5012000000000000000000000000000000000000000000000000000000000000000008a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc688527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f401b175ac686800000000"); + raw_tx->input[0].witness = NULL; + tx_must_be_eq(raw_tx, txs[1]); + + /* BOLT #3: + * + * output htlc_timeout_tx 2: 020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219701000000000000000001d0070000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100d5275b3619953cb0c3b5aa577f04bc512380e60fa551762ce3d7a1bb7401cff9022037237ab0dac3fe100cde094e82e2bed9ba0ed1bb40154b48e56aa70f259e608b01483045022100c89172099507ff50f4c925e6c5150e871fb6e83dd73ff9fbb72f6ce829a9633f02203a63821d9162e99f9be712a68f9e589483994feae2661e4546cd5b6cec007be501008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000 + */ + raw_tx = tx_from_hex(tmpctx, "020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219701000000000000000001d0070000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100d5275b3619953cb0c3b5aa577f04bc512380e60fa551762ce3d7a1bb7401cff9022037237ab0dac3fe100cde094e82e2bed9ba0ed1bb40154b48e56aa70f259e608b01483045022100c89172099507ff50f4c925e6c5150e871fb6e83dd73ff9fbb72f6ce829a9633f02203a63821d9162e99f9be712a68f9e589483994feae2661e4546cd5b6cec007be501008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a914b43e1b38138a41b37f7cd9a1d274bc63e3a9b5d188ac6868f6010000"); + raw_tx->input[0].witness = NULL; + tx_must_be_eq(raw_tx, txs[2]); + + /* BOLT #3: + * + * output htlc_success_tx 1: 020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219702000000000000000001d0070000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402201b63ec807771baf4fdff523c644080de17f1da478989308ad13a58b51db91d360220568939d38c9ce295adba15665fa68f51d967e8ed14a007b751540a80b325f20201483045022100def389deab09cee69eaa1ec14d9428770e45bcbe9feb46468ecf481371165c2f022015d2e3c46600b2ebba8dcc899768874cc6851fd1ecb3fffd15db1cc3de7e10da012001010101010101010101010101010101010101010101010101010101010101018a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac686800000000 + */ + raw_tx = tx_from_hex(tmpctx, "020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219702000000000000000001d0070000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402201b63ec807771baf4fdff523c644080de17f1da478989308ad13a58b51db91d360220568939d38c9ce295adba15665fa68f51d967e8ed14a007b751540a80b325f20201483045022100def389deab09cee69eaa1ec14d9428770e45bcbe9feb46468ecf481371165c2f022015d2e3c46600b2ebba8dcc899768874cc6851fd1ecb3fffd15db1cc3de7e10da012001010101010101010101010101010101010101010101010101010101010101018a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac686800000000"); + raw_tx->input[0].witness = NULL; + tx_must_be_eq(raw_tx, txs[3]); + + /* BOLT #3: + * + * output htlc_timeout_tx 3: 020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219703000000000000000001b80b0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100daee1808f9861b6c3ecd14f7b707eca02dd6bdfc714ba2f33bc8cdba507bb182022026654bf8863af77d74f51f4e0b62d461a019561bb12acb120d3f7195d148a554014730440220643aacb19bbb72bd2b635bc3f7375481f5981bace78cdd8319b2988ffcc6704202203d27784ec8ad51ed3bd517a05525a5139bb0b755dd719e0054332d186ac0872701008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000 + */ + raw_tx = tx_from_hex(tmpctx, "020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219703000000000000000001b80b0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0500483045022100daee1808f9861b6c3ecd14f7b707eca02dd6bdfc714ba2f33bc8cdba507bb182022026654bf8863af77d74f51f4e0b62d461a019561bb12acb120d3f7195d148a554014730440220643aacb19bbb72bd2b635bc3f7375481f5981bace78cdd8319b2988ffcc6704202203d27784ec8ad51ed3bd517a05525a5139bb0b755dd719e0054332d186ac0872701008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9148a486ff2e31d6158bf39e2608864d63fefd09d5b88ac6868f7010000"); + raw_tx->input[0].witness = NULL; + tx_must_be_eq(raw_tx, txs[4]); + + /* BOLT #3: + * + * output htlc_success_tx 4: 020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219704000000000000000001a00f0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402207e0410e45454b0978a623f36a10626ef17b27d9ad44e2760f98cfa3efb37924f0220220bd8acd43ecaa916a80bd4f919c495a2c58982ce7c8625153f8596692a801d014730440220549e80b4496803cbc4a1d09d46df50109f546d43fbbf86cd90b174b1484acd5402205f12a4f995cb9bded597eabfee195a285986aa6d93ae5bb72507ebc6a4e2349e012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000 + */ + raw_tx = tx_from_hex(tmpctx, "020000000001018154ecccf11a5fb56c39654c4deb4d2296f83c69268280b94d021370c94e219704000000000000000001a00f0000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402207e0410e45454b0978a623f36a10626ef17b27d9ad44e2760f98cfa3efb37924f0220220bd8acd43ecaa916a80bd4f919c495a2c58982ce7c8625153f8596692a801d014730440220549e80b4496803cbc4a1d09d46df50109f546d43fbbf86cd90b174b1484acd5402205f12a4f995cb9bded597eabfee195a285986aa6d93ae5bb72507ebc6a4e2349e012004040404040404040404040404040404040404040404040404040404040404048a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a91418bc1a114ccf9c052d3d23e28d3b0a9d1227434288527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f801b175ac686800000000"); + raw_tx->input[0].witness = NULL; + tx_must_be_eq(raw_tx, txs[5]); + + /* FIXME: Compare HTLCs for these too! */ for (i = 0; i < ARRAY_SIZE(feerates); i++) { feerate_per_kw = feerates[i]; @@ -468,13 +557,13 @@ int main(void) htlcs, &htlc_map, 0x2bb038521914 ^ 42, LOCAL); - tx = channel_tx(tmpctx, lchannel, &local_per_commitment_point, - &htlc_map, LOCAL); - tx_must_be_eq(tx, raw_tx); + txs = channel_txs(tmpctx, &htlc_map, &wscripts, + lchannel, &local_per_commitment_point, LOCAL); + tx_must_be_eq(txs[0], raw_tx); - tx = channel_tx(tmpctx, rchannel, &local_per_commitment_point, - &htlc_map, REMOTE); - tx_must_be_eq(tx, raw_tx); + txs2 = channel_txs(tmpctx, &htlc_map, &wscripts, + rchannel, &local_per_commitment_point, REMOTE); + txs_must_be_eq(txs, txs2); } /* No memory leaks please */