diff --git a/lightningd/Makefile b/lightningd/Makefile index 6cc220dcf..6bca00b05 100644 --- a/lightningd/Makefile +++ b/lightningd/Makefile @@ -99,6 +99,7 @@ LIGHTNINGD_COMMON_OBJS := \ common/hsm_encryption.o \ common/htlc_state.o \ common/htlc_trim.o \ + common/htlc_tx.o \ common/htlc_wire.o \ common/invoice_path_id.o \ common/key_derive.o \ diff --git a/lightningd/onchain_control.c b/lightningd/onchain_control.c index beaba49e4..bfbf9ad8b 100644 --- a/lightningd/onchain_control.c +++ b/lightningd/onchain_control.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -550,6 +551,12 @@ struct onchain_signing_info { struct { struct secret remote_per_commitment_secret; } spend_penalty; + /* WIRE_ONCHAIND_SPEND_HTLC_SUCCESS */ + struct { + u64 commit_num; + struct bitcoin_signature remote_htlc_sig; + struct preimage preimage; + } htlc_success; } u; }; @@ -595,6 +602,22 @@ static u8 *sign_penalty(const tal_t *ctx, info->channel->dbid); } +static u8 *sign_htlc_success(const tal_t *ctx, + const struct bitcoin_tx *tx, + const struct onchain_signing_info *info) +{ + const bool anchor_outputs = channel_has(info->channel, OPT_ANCHOR_OUTPUTS); + + assert(info->msgtype == WIRE_ONCHAIND_SPEND_HTLC_SUCCESS); + return towire_hsmd_sign_any_local_htlc_tx(ctx, + info->u.htlc_success.commit_num, + tx, info->wscript, + anchor_outputs, + 0, + &info->channel->peer->id, + info->channel->dbid); +} + /* Matches bitcoin_witness_sig_and_element! */ static const struct onchain_witness_element ** onchain_witness_sig_and_element(const tal_t *ctx, u8 **witness) @@ -613,6 +636,24 @@ onchain_witness_sig_and_element(const tal_t *ctx, u8 **witness) return cast_const2(const struct onchain_witness_element **, welements); } +/* Matches bitcoin_witness_htlc_success_tx & bitcoin_witness_htlc_timeout_tx! */ +static const struct onchain_witness_element ** +onchain_witness_htlc_tx(const tal_t *ctx, u8 **witness) +{ + struct onchain_witness_element **welements; + welements = tal_arr(ctx, struct onchain_witness_element *, + tal_count(witness)); + + for (size_t i = 0; i < tal_count(welements); i++) { + welements[i] = tal(welements, struct onchain_witness_element); + /* See bitcoin_witness_htlc_success_tx / bitcoin_witness_htlc_timeout_tx */ + welements[i]->is_signature = (i == 1 || i == 2); + welements[i]->witness = tal_dup_talarr(welements[i], u8, + witness[i]); + } + return cast_const2(const struct onchain_witness_element **, welements); +} + /* Always sets *welements, returns tx. Sets *worthwhile to false if * it wasn't worthwhile at the given feerate (and it had to drop feerate). * Returns NULL iff it called channel_internal_error(). @@ -717,6 +758,29 @@ static bool consider_onchain_rebroadcast(struct channel *channel, return true; } +static bool consider_onchain_htlc_tx_rebroadcast(struct channel *channel, + const struct bitcoin_tx **tx, + struct onchain_signing_info *info) +{ + /* FIXME: Implement rbf! */ + return true; +} + +/* We want to mine a success tx before they can timeout */ +static u32 htlc_incoming_deadline(const struct channel *channel, u64 htlc_id) +{ + struct htlc_in *hin; + + hin = find_htlc_in(channel->peer->ld->htlcs_in, channel, htlc_id); + if (!hin) { + log_broken(channel->log, "No htlc IN %"PRIu64", using infinite deadline", + htlc_id); + return infinite_block_deadline(channel->peer->ld->topology); + } + + return hin->cltv_expiry - 1; +} + /* Create the onchain tx and tell onchaind about it */ static void create_onchain_tx(struct channel *channel, const struct bitcoin_outpoint *out, @@ -849,6 +913,80 @@ static void handle_onchaind_spend_penalty(struct channel *channel, __func__); } +static void handle_onchaind_spend_htlc_success(struct channel *channel, + const u8 *msg) +{ + struct lightningd *ld = channel->peer->ld; + struct onchain_signing_info *info; + struct bitcoin_outpoint out; + struct amount_sat out_sats, fee; + u64 htlc_id; + u8 *htlc_wscript; + struct bitcoin_tx *tx; + u8 **witness; + struct bitcoin_signature sig; + const struct onchain_witness_element **welements; + const bool anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS); + + info = new_signing_info(msg, channel, WIRE_ONCHAIND_SPEND_HTLC_SUCCESS); + info->minblock = 0; + + if (!fromwire_onchaind_spend_htlc_success(info, msg, + &out, &out_sats, &fee, + &htlc_id, + &info->u.htlc_success.commit_num, + &info->u.htlc_success.remote_htlc_sig, + &info->u.htlc_success.preimage, + &info->wscript, + &htlc_wscript)) { + channel_internal_error(channel, "Invalid onchaind_spend_htlc_success %s", + tal_hex(tmpctx, msg)); + return; + } + + /* BOLT #3: + * * locktime: `0` for HTLC-success, `cltv_expiry` for HTLC-timeout + */ + tx = htlc_tx(NULL, chainparams, &out, info->wscript, out_sats, htlc_wscript, fee, + 0, anchor_outputs); + tal_free(htlc_wscript); + if (!tx) { + /* Can only happen if fee > out_sats */ + channel_internal_error(channel, "Invalid onchaind_spend_htlc_success %s", + tal_hex(tmpctx, msg)); + return; + } + + /* FIXME: tell onchaind if HTLC is too small for current + * feerate! */ + info->deadline_block = htlc_incoming_deadline(channel, htlc_id); + + /* Now sign, and set witness */ + msg = sign_htlc_success(NULL, tx, info); + if (!wire_sync_write(ld->hsm_fd, take(msg))) + fatal("Writing sign request to hsm"); + msg = wire_sync_read(tmpctx, ld->hsm_fd); + if (!msg || !fromwire_hsmd_sign_tx_reply(msg, &sig)) + fatal("Reading sign_tx_reply: %s", tal_hex(tmpctx, msg)); + + witness = bitcoin_witness_htlc_success_tx(NULL, &sig, + &info->u.htlc_success.remote_htlc_sig, + &info->u.htlc_success.preimage, + info->wscript); + welements = onchain_witness_htlc_tx(tmpctx, witness); + bitcoin_tx_input_set_witness(tx, 0, take(witness)); + + log_debug(channel->log, "Broadcast for onchaind tx %s", + type_to_string(tmpctx, struct bitcoin_tx, tx)); + broadcast_tx(channel->peer->ld->topology, + channel, take(tx), NULL, false, + info->minblock, NULL, + consider_onchain_htlc_tx_rebroadcast, take(info)); + + msg = towire_onchaind_spend_created(NULL, true, welements); + subd_send_msg(channel->owner, take(msg)); +} + static unsigned int onchain_msg(struct subd *sd, const u8 *msg, const int *fds UNUSED) { enum onchaind_wire t = fromwire_peektype(msg); @@ -906,6 +1044,10 @@ static unsigned int onchain_msg(struct subd *sd, const u8 *msg, const int *fds U handle_onchaind_spend_penalty(sd->channel, msg); break; + case WIRE_ONCHAIND_SPEND_HTLC_SUCCESS: + handle_onchaind_spend_htlc_success(sd->channel, msg); + break; + /* We send these, not receive them */ case WIRE_ONCHAIND_INIT: case WIRE_ONCHAIND_SPENT: diff --git a/onchaind/onchaind.c b/onchaind/onchaind.c index da9bcaa92..081d57c86 100644 --- a/onchaind/onchaind.c +++ b/onchaind/onchaind.c @@ -550,14 +550,30 @@ static bool set_htlc_timeout_fee(struct bitcoin_tx *tx, &keyset->other_htlc_key, remotesig); } -static void set_htlc_success_fee(struct bitcoin_tx *tx, - const struct bitcoin_signature *remotesig, - const u8 *wscript) +static struct amount_sat get_htlc_success_fee(struct tracked_output *out) { static struct amount_sat fee = AMOUNT_SAT_INIT(UINT64_MAX); - struct amount_sat amt; - struct amount_asset asset; size_t weight; + struct amount_msat htlc_amount; + struct bitcoin_tx *tx; + + /* We only grind once, since they're all equiv. */ + if (!amount_sat_eq(fee, AMOUNT_SAT(UINT64_MAX))) + return fee; + + if (!amount_sat_to_msat(&htlc_amount, out->sat)) + status_failed(STATUS_FAIL_INTERNAL_ERROR, + "Overflow in get_htlc_success_fee %s", + type_to_string(tmpctx, + struct amount_sat, + &out->sat)); + tx = htlc_success_tx(tmpctx, chainparams, + &out->outpoint, + out->wscript, + htlc_amount, + to_self_delay[LOCAL], + 0, + keyset, option_anchor_outputs); /* BOLT #3: * @@ -574,45 +590,21 @@ static void set_htlc_success_fee(struct bitcoin_tx *tx, weight = 703; weight += elements_tx_overhead(chainparams, 1, 1); - if (amount_sat_eq(fee, AMOUNT_SAT(UINT64_MAX))) { - if (!grind_htlc_tx_fee(&fee, tx, remotesig, wscript, weight)) - status_failed(STATUS_FAIL_INTERNAL_ERROR, - "htlc_success_fee can't be found " - "for tx %s (weight %zu, feerate %u-%u), signature %s, wscript %s", - type_to_string(tmpctx, struct bitcoin_tx, - tx), - weight, - min_possible_feerate, max_possible_feerate, - type_to_string(tmpctx, - struct bitcoin_signature, - remotesig), - tal_hex(tmpctx, wscript)); - return; + if (!grind_htlc_tx_fee(&fee, tx, out->remote_htlc_sig, + out->wscript, weight)) { + status_failed(STATUS_FAIL_INTERNAL_ERROR, + "htlc_success_fee can't be found " + "for tx %s (weight %zu, feerate %u-%u), signature %s, wscript %s", + type_to_string(tmpctx, struct bitcoin_tx, tx), + weight, + min_possible_feerate, max_possible_feerate, + type_to_string(tmpctx, + struct bitcoin_signature, + out->remote_htlc_sig), + tal_hex(tmpctx, out->wscript)); } - asset = bitcoin_tx_output_get_amount(tx, 0); - assert(amount_asset_is_main(&asset)); - amt = amount_asset_to_sat(&asset); - - if (!amount_sat_sub(&amt, amt, fee)) - status_failed(STATUS_FAIL_INTERNAL_ERROR, - "Cannot deduct htlc-success fee %s from tx %s", - type_to_string(tmpctx, struct amount_sat, &fee), - type_to_string(tmpctx, struct bitcoin_tx, tx)); - bitcoin_tx_output_set_amount(tx, 0, amt); - bitcoin_tx_finalize(tx); - - if (check_tx_sig(tx, 0, NULL, wscript, - &keyset->other_htlc_key, remotesig)) - return; - - status_failed(STATUS_FAIL_INTERNAL_ERROR, - "htlc_success_fee %s failed sigcheck " - " for tx %s, signature %s, wscript %s", - type_to_string(tmpctx, struct amount_sat, &fee), - type_to_string(tmpctx, struct bitcoin_tx, tx), - type_to_string(tmpctx, struct bitcoin_signature, remotesig), - tal_hex(tmpctx, wscript)); + return fee; } static u8 *remote_htlc_to_us(const tal_t *ctx, @@ -1745,14 +1737,12 @@ static void handle_preimage(struct tracked_output **outs, size_t i; struct sha256 sha; struct ripemd160 ripemd; - u8 **witness; sha256(&sha, preimage, sizeof(*preimage)); ripemd160(&ripemd, &sha, sizeof(sha)); for (i = 0; i < tal_count(outs); i++) { struct bitcoin_tx *tx; - struct bitcoin_signature sig; if (outs[i]->output_type != THEIR_HTLC) continue; @@ -1788,29 +1778,29 @@ static void handle_preimage(struct tracked_output **outs, * HTLC-success transaction. */ if (outs[i]->remote_htlc_sig) { - struct amount_msat htlc_amount; - if (!amount_sat_to_msat(&htlc_amount, outs[i]->sat)) - status_failed(STATUS_FAIL_INTERNAL_ERROR, - "Overflow in output %zu %s", - i, - type_to_string(tmpctx, - struct amount_sat, - &outs[i]->sat)); - tx = htlc_success_tx(outs[i], chainparams, - &outs[i]->outpoint, - outs[i]->wscript, - htlc_amount, - to_self_delay[LOCAL], - 0, - keyset, option_anchor_outputs); - set_htlc_success_fee(tx, outs[i]->remote_htlc_sig, - outs[i]->wscript); - hsm_sign_local_htlc_tx(tx, outs[i]->wscript, &sig); - witness = bitcoin_witness_htlc_success_tx( - tx, &sig, outs[i]->remote_htlc_sig, preimage, - outs[i]->wscript); - bitcoin_tx_input_set_witness(tx, 0, take(witness)); - propose_resolution(outs[i], tx, 0, OUR_HTLC_SUCCESS_TX); + struct amount_sat fee; + const u8 *msg; + const u8 *htlc_wscript; + + /* FIXME: lightningd could derive this itself? */ + htlc_wscript = bitcoin_wscript_htlc_tx(tmpctx, + to_self_delay[LOCAL], + &keyset->self_revocation_key, + &keyset->self_delayed_payment_key); + + fee = get_htlc_success_fee(outs[i]); + msg = towire_onchaind_spend_htlc_success(NULL, + &outs[i]->outpoint, + outs[i]->sat, + fee, + outs[i]->htlc.id, + commit_num, + outs[i]->remote_htlc_sig, + preimage, + outs[i]->wscript, + htlc_wscript); + propose_immediate_resolution(outs[i], take(msg), + OUR_HTLC_SUCCESS_TX); } else { enum tx_type tx_type = THEIR_HTLC_FULFILL_TO_US; @@ -1969,6 +1959,7 @@ static void wait_for_resolved(struct tracked_output **outs) case WIRE_ONCHAIND_NOTIFY_COIN_MVT: case WIRE_ONCHAIND_SPEND_TO_US: case WIRE_ONCHAIND_SPEND_PENALTY: + case WIRE_ONCHAIND_SPEND_HTLC_SUCCESS: break; } master_badmsg(-1, msg); diff --git a/onchaind/onchaind_wire.csv b/onchaind/onchaind_wire.csv index 949dba431..98f568380 100644 --- a/onchaind/onchaind_wire.csv +++ b/onchaind/onchaind_wire.csv @@ -159,6 +159,20 @@ msgdata,onchaind_spend_penalty,stack_elem,u8,stack_elem_len msgdata,onchaind_spend_penalty,wscript_len,u32, msgdata,onchaind_spend_penalty,wscript,u8,wscript_len +# We tell lightningd to create, sign and broadcast this htlc_success tx: +msgtype,onchaind_spend_htlc_success,5042 +msgdata,onchaind_spend_htlc_success,outpoint,bitcoin_outpoint, +msgdata,onchaind_spend_htlc_success,outpoint_amount,amount_sat, +msgdata,onchaind_spend_htlc_success,fee,amount_sat, +msgdata,onchaind_spend_htlc_success,htlc_id,u64, +msgdata,onchaind_spend_htlc_success,commit_num,u64, +msgdata,onchaind_spend_htlc_success,remote_htlc_sig,bitcoin_signature, +msgdata,onchaind_spend_htlc_success,preimage,preimage, +msgdata,onchaind_spend_htlc_success,wscript_len,u32, +msgdata,onchaind_spend_htlc_success,wscript,u8,wscript_len +msgdata,onchaind_spend_htlc_success,htlc_wscript_len,u32, +msgdata,onchaind_spend_htlc_success,htlc_wscript,u8,htlc_wscript_len + subtype,onchain_witness_element subtypedata,onchain_witness_element,is_signature,bool, subtypedata,onchain_witness_element,len,u32, diff --git a/onchaind/test/run-grind_feerate-bug.c b/onchaind/test/run-grind_feerate-bug.c index 563de5830..3a44fb5a8 100644 --- a/onchaind/test/run-grind_feerate-bug.c +++ b/onchaind/test/run-grind_feerate-bug.c @@ -282,6 +282,9 @@ u8 *towire_onchaind_missing_htlc_output(const tal_t *ctx UNNEEDED, const struct /* Generated stub for towire_onchaind_notify_coin_mvt */ u8 *towire_onchaind_notify_coin_mvt(const tal_t *ctx UNNEEDED, const struct chain_coin_mvt *mvt UNNEEDED) { fprintf(stderr, "towire_onchaind_notify_coin_mvt called!\n"); abort(); } +/* Generated stub for towire_onchaind_spend_htlc_success */ +u8 *towire_onchaind_spend_htlc_success(const tal_t *ctx UNNEEDED, const struct bitcoin_outpoint *outpoint UNNEEDED, struct amount_sat outpoint_amount UNNEEDED, struct amount_sat fee UNNEEDED, u64 htlc_id UNNEEDED, u64 commit_num UNNEEDED, const struct bitcoin_signature *remote_htlc_sig UNNEEDED, const struct preimage *preimage UNNEEDED, const u8 *wscript UNNEEDED, const u8 *htlc_wscript UNNEEDED) +{ fprintf(stderr, "towire_onchaind_spend_htlc_success called!\n"); abort(); } /* Generated stub for towire_onchaind_spend_penalty */ u8 *towire_onchaind_spend_penalty(const tal_t *ctx UNNEEDED, const struct bitcoin_outpoint *outpoint UNNEEDED, struct amount_sat outpoint_amount UNNEEDED, const struct secret *remote_per_commitment_secret UNNEEDED, const u8 *stack_elem UNNEEDED, const u8 *wscript UNNEEDED) { fprintf(stderr, "towire_onchaind_spend_penalty called!\n"); abort(); } diff --git a/onchaind/test/run-grind_feerate.c b/onchaind/test/run-grind_feerate.c index 4ffdb889e..5b4d8a51c 100644 --- a/onchaind/test/run-grind_feerate.c +++ b/onchaind/test/run-grind_feerate.c @@ -314,6 +314,9 @@ u8 *towire_onchaind_missing_htlc_output(const tal_t *ctx UNNEEDED, const struct /* Generated stub for towire_onchaind_notify_coin_mvt */ u8 *towire_onchaind_notify_coin_mvt(const tal_t *ctx UNNEEDED, const struct chain_coin_mvt *mvt UNNEEDED) { fprintf(stderr, "towire_onchaind_notify_coin_mvt called!\n"); abort(); } +/* Generated stub for towire_onchaind_spend_htlc_success */ +u8 *towire_onchaind_spend_htlc_success(const tal_t *ctx UNNEEDED, const struct bitcoin_outpoint *outpoint UNNEEDED, struct amount_sat outpoint_amount UNNEEDED, struct amount_sat fee UNNEEDED, u64 htlc_id UNNEEDED, u64 commit_num UNNEEDED, const struct bitcoin_signature *remote_htlc_sig UNNEEDED, const struct preimage *preimage UNNEEDED, const u8 *wscript UNNEEDED, const u8 *htlc_wscript UNNEEDED) +{ fprintf(stderr, "towire_onchaind_spend_htlc_success called!\n"); abort(); } /* Generated stub for towire_onchaind_spend_penalty */ u8 *towire_onchaind_spend_penalty(const tal_t *ctx UNNEEDED, const struct bitcoin_outpoint *outpoint UNNEEDED, struct amount_sat outpoint_amount UNNEEDED, const struct secret *remote_per_commitment_secret UNNEEDED, const u8 *stack_elem UNNEEDED, const u8 *wscript UNNEEDED) { fprintf(stderr, "towire_onchaind_spend_penalty called!\n"); abort(); } diff --git a/tests/test_closing.py b/tests/test_closing.py index 41c0ec3fd..4b5534180 100644 --- a/tests/test_closing.py +++ b/tests/test_closing.py @@ -1299,17 +1299,16 @@ def test_penalty_htlc_tx_fulfill(node_factory, bitcoind, chainparams): # l2 moves on for closed l3 bitcoind.generate_block(1) l2.daemon.wait_for_log('to ONCHAIN') - needle = l2.daemon.logsearch_start - l2.daemon.wait_for_log('Propose handling OUR_UNILATERAL/THEIR_HTLC by OUR_HTLC_SUCCESS_TX .* after 0 blocks') - l2.wait_for_onchaind_broadcast('OUR_HTLC_SUCCESS_TX', - 'OUR_UNILATERAL/THEIR_HTLC') - l2.daemon.logsearch_start = needle - ((_, _, blocks),) = l2.wait_for_onchaind_tx('OUR_DELAYED_RETURN_TO_WALLET', - 'OUR_UNILATERAL/DELAYED_OUTPUT_TO_US') - assert blocks == 4 + ((_, txid1, blocks1), (_, _, blocks2)) = \ + l2.wait_for_onchaind_tx('OUR_HTLC_SUCCESS_TX', + 'OUR_UNILATERAL/THEIR_HTLC', + 'OUR_DELAYED_RETURN_TO_WALLET', + 'OUR_UNILATERAL/DELAYED_OUTPUT_TO_US') + assert blocks1 == 0 + assert blocks2 == 4 - bitcoind.generate_block(1) + bitcoind.generate_block(1, wait_for_mempool=txid1) ((_, _, blocks),) = l2.wait_for_onchaind_tx('OUR_DELAYED_RETURN_TO_WALLET', 'OUR_HTLC_SUCCESS_TX/DELAYED_OUTPUT_TO_US') assert blocks == 4 @@ -1501,13 +1500,13 @@ def test_penalty_htlc_tx_timeout(node_factory, bitcoind, chainparams): # l2 moves on for closed l3 bitcoind.generate_block(1, wait_for_mempool=1) l2.daemon.wait_for_log('to ONCHAIN') - l2.daemon.wait_for_logs(['Propose handling OUR_UNILATERAL/OUR_HTLC by OUR_HTLC_TIMEOUT_TX .* after 16 blocks', - 'Propose handling OUR_UNILATERAL/THEIR_HTLC by OUR_HTLC_SUCCESS_TX .* after 0 blocks']) + l2.daemon.wait_for_log('Propose handling OUR_UNILATERAL/OUR_HTLC by OUR_HTLC_TIMEOUT_TX .* after 16 blocks') - l2.wait_for_onchaind_broadcast('OUR_HTLC_SUCCESS_TX', - 'OUR_UNILATERAL/THEIR_HTLC') + ((_, txid, blocks),) = l2.wait_for_onchaind_tx('OUR_HTLC_SUCCESS_TX', + 'OUR_UNILATERAL/THEIR_HTLC') + assert blocks == 0 - bitcoind.generate_block(1, wait_for_mempool=1) + bitcoind.generate_block(1, wait_for_mempool=txid) ((_, txid, blocks),) = l2.wait_for_onchaind_tx('OUR_DELAYED_RETURN_TO_WALLET', 'OUR_HTLC_SUCCESS_TX/DELAYED_OUTPUT_TO_US') assert blocks == 4 @@ -2253,17 +2252,17 @@ def test_onchain_middleman_simple(node_factory, bitcoind): l1.daemon.wait_for_log(' to ONCHAIN') l2.daemon.wait_for_log('OUR_UNILATERAL/THEIR_HTLC') - needle = l2.daemon.logsearch_start # l2 should fulfill HTLC onchain, and spend to-us (any order) - l2.wait_for_onchaind_broadcast('OUR_HTLC_SUCCESS_TX', - 'OUR_UNILATERAL/THEIR_HTLC') - l2.daemon.logsearch_start = needle - ((_, txid1, blocks),) = l2.wait_for_onchaind_tx('OUR_DELAYED_RETURN_TO_WALLET', - 'OUR_UNILATERAL/DELAYED_OUTPUT_TO_US') - assert blocks == 4 + ((_, txid1, blocks1), (_, txid2, blocks2)) = \ + l2.wait_for_onchaind_tx('OUR_HTLC_SUCCESS_TX', + 'OUR_UNILATERAL/THEIR_HTLC', + 'OUR_DELAYED_RETURN_TO_WALLET', + 'OUR_UNILATERAL/DELAYED_OUTPUT_TO_US') + assert blocks1 == 0 + assert blocks2 == 4 # Payment should succeed. - l1.bitcoin.generate_block(1, wait_for_mempool=1) + l1.bitcoin.generate_block(1, wait_for_mempool=txid1) l1.daemon.wait_for_log('THEIR_UNILATERAL/OUR_HTLC gave us preimage') err = q.get(timeout=10) if err: @@ -2272,16 +2271,16 @@ def test_onchain_middleman_simple(node_factory, bitcoind): t.join(timeout=1) assert not t.is_alive() - ((_, txid2, blocks),) = l2.wait_for_onchaind_tx('OUR_DELAYED_RETURN_TO_WALLET', + ((_, txid3, blocks),) = l2.wait_for_onchaind_tx('OUR_DELAYED_RETURN_TO_WALLET', 'OUR_HTLC_SUCCESS_TX/DELAYED_OUTPUT_TO_US') assert blocks == 4 # Four more, l2 can spend to-us, and we can spend htlc tx. bitcoind.generate_block(3) - bitcoind.generate_block(1, wait_for_mempool=txid1) + bitcoind.generate_block(1, wait_for_mempool=txid2) # 100 blocks after last spend, l2 should be done. - l1.bitcoin.generate_block(100, wait_for_mempool=txid2) + l1.bitcoin.generate_block(100, wait_for_mempool=txid3) l2.daemon.wait_for_log('onchaind complete, forgetting peer') # Verify accounting for l1 & l2 @@ -3115,9 +3114,10 @@ def test_permfail_htlc_in(node_factory, bitcoind, executor): l2.daemon.wait_for_log('Propose handling OUR_UNILATERAL/THEIR_HTLC by THEIR_HTLC_TIMEOUT_TO_THEM \\(IGNORING\\) after 6 blocks') l1.daemon.wait_for_log('Propose handling THEIR_UNILATERAL/OUR_HTLC by OUR_HTLC_TIMEOUT_TO_US (.*) after 6 blocks') # l2 then gets preimage, uses it instead of ignoring - l2.wait_for_onchaind_broadcast('OUR_HTLC_SUCCESS_TX', - 'OUR_UNILATERAL/THEIR_HTLC') - bitcoind.generate_block(1) + ((_, txid, blocks),) = l2.wait_for_onchaind_tx('OUR_HTLC_SUCCESS_TX', + 'OUR_UNILATERAL/THEIR_HTLC') + assert blocks == 0 + bitcoind.generate_block(1, wait_for_mempool=txid) # OK, l1 sees l2 fulfill htlc. l1.daemon.wait_for_log('THEIR_UNILATERAL/OUR_HTLC gave us preimage') diff --git a/tests/test_misc.py b/tests/test_misc.py index f7ff09b1b..2150391e0 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -427,9 +427,10 @@ def test_htlc_in_timeout(node_factory, bitcoind, executor): l1.daemon.wait_for_log(' to ONCHAIN') # L2 will collect HTLC (iff no shadow route) - l2.daemon.wait_for_log('Propose handling OUR_UNILATERAL/THEIR_HTLC by OUR_HTLC_SUCCESS_TX .* after 0 blocks') - l2.daemon.wait_for_log('sendrawtx exit 0') - bitcoind.generate_block(1, wait_for_mempool=1) + ((_, txid, blocks),) = l2.wait_for_onchaind_tx('OUR_HTLC_SUCCESS_TX', + 'OUR_UNILATERAL/THEIR_HTLC') + assert blocks == 0 + bitcoind.generate_block(1, wait_for_mempool=txid) ((rawtx, txid, blocks),) = l2.wait_for_onchaind_tx('OUR_DELAYED_RETURN_TO_WALLET', 'OUR_HTLC_SUCCESS_TX/DELAYED_OUTPUT_TO_US') assert blocks == 4