diff --git a/lightningd/onchain_control.c b/lightningd/onchain_control.c index 734d63a3b..523cef316 100644 --- a/lightningd/onchain_control.c +++ b/lightningd/onchain_control.c @@ -557,6 +557,11 @@ struct onchain_signing_info { struct bitcoin_signature remote_htlc_sig; struct preimage preimage; } htlc_success; + /* WIRE_ONCHAIND_SPEND_HTLC_TIMEOUT */ + struct { + u64 commit_num; + struct bitcoin_signature remote_htlc_sig; + } htlc_timeout; /* WIRE_ONCHAIND_SPEND_FULFILL */ struct { struct pubkey remote_per_commitment_point; @@ -623,6 +628,22 @@ static u8 *sign_htlc_success(const tal_t *ctx, info->channel->dbid); } +static u8 *sign_htlc_timeout(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_TIMEOUT); + return towire_hsmd_sign_any_local_htlc_tx(ctx, + info->u.htlc_timeout.commit_num, + tx, info->wscript, + anchor_outputs, + 0, + &info->channel->peer->id, + info->channel->dbid); +} + static u8 *sign_fulfill(const tal_t *ctx, const struct bitcoin_tx *tx, const struct onchain_signing_info *info) @@ -802,6 +823,28 @@ static u32 htlc_incoming_deadline(const struct channel *channel, u64 htlc_id) return hin->cltv_expiry - 1; } +/* If there's a corresponding incoming HTLC, we want this mined in time so + * we can fail incoming before incoming peer closes on us! */ +static u32 htlc_outgoing_incoming_deadline(const struct channel *channel, u64 htlc_id) +{ + struct htlc_out *hout; + + hout = find_htlc_out(channel->peer->ld->htlcs_out, channel, htlc_id); + if (!hout) { + log_broken(channel->log, "No htlc OUT %"PRIu64", using infinite deadline", + htlc_id); + return infinite_block_deadline(channel->peer->ld->topology); + } + + /* If it's ours, no real pressure, but let's avoid leaking + * that information by using our standard setting. */ + if (!hout->in) + return hout->cltv_expiry; + + /* Give us at least six blocks to redeem! */ + return hout->in->cltv_expiry - 6; +} + /* Create the onchain tx and tell onchaind about it */ static void create_onchain_tx(struct channel *channel, const struct bitcoin_outpoint *out, @@ -1053,6 +1096,82 @@ static void handle_onchaind_spend_htlc_success(struct channel *channel, subd_send_msg(channel->owner, take(msg)); } +static void handle_onchaind_spend_htlc_timeout(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; + u32 cltv_expiry; + 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_TIMEOUT); + + if (!fromwire_onchaind_spend_htlc_timeout(info, msg, + &out, &out_sats, &fee, + &htlc_id, + &cltv_expiry, + &info->u.htlc_timeout.commit_num, + &info->u.htlc_timeout.remote_htlc_sig, + &info->wscript, + &htlc_wscript)) { + channel_internal_error(channel, "Invalid onchaind_spend_htlc_timeout %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, + cltv_expiry, anchor_outputs); + tal_free(htlc_wscript); + if (!tx) { + /* Can only happen if fee > out_sats */ + channel_internal_error(channel, "Invalid onchaind_spend_htlc_timeout %s", + tal_hex(tmpctx, msg)); + return; + } + + /* FIXME: tell onchaind if HTLC is too small for current + * feerate! */ + info->deadline_block = htlc_outgoing_incoming_deadline(channel, htlc_id); + + /* nLocktime: we have to be *after* that block! */ + info->minblock = cltv_expiry + 1; + + /* Now sign, and set witness */ + msg = sign_htlc_timeout(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_timeout_tx(NULL, &sig, + &info->u.htlc_timeout.remote_htlc_sig, + 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); @@ -1114,6 +1233,10 @@ static unsigned int onchain_msg(struct subd *sd, const u8 *msg, const int *fds U handle_onchaind_spend_htlc_success(sd->channel, msg); break; + case WIRE_ONCHAIND_SPEND_HTLC_TIMEOUT: + handle_onchaind_spend_htlc_timeout(sd->channel, msg); + break; + case WIRE_ONCHAIND_SPEND_FULFILL: handle_onchaind_spend_fulfill(sd->channel, msg); break; diff --git a/onchaind/onchaind.c b/onchaind/onchaind.c index ba27e3a5e..0e8ba33fb 100644 --- a/onchaind/onchaind.c +++ b/onchaind/onchaind.c @@ -706,24 +706,6 @@ static struct bitcoin_tx *tx_to_us(const tal_t *ctx, return tx; } -static void hsm_sign_local_htlc_tx(struct bitcoin_tx *tx, - const u8 *wscript, - struct bitcoin_signature *sig) -{ - u8 *msg = towire_hsmd_sign_local_htlc_tx(NULL, commit_num, - tx, wscript, - option_anchor_outputs); - - if (!wire_sync_write(HSM_FD, take(msg))) - status_failed(STATUS_FAIL_HSM_IO, - "Writing sign_local_htlc_tx to hsm"); - msg = wire_sync_read(tmpctx, HSM_FD); - if (!msg || !fromwire_hsmd_sign_tx_reply(msg, sig)) - status_failed(STATUS_FAIL_HSM_IO, - "Reading sign_local_htlc_tx: %s", - tal_hex(tmpctx, msg)); -} - static void hsm_get_per_commitment_point(struct pubkey *per_commitment_point) { u8 *msg = towire_hsmd_get_per_commitment_point(NULL, commit_num); @@ -1960,6 +1942,7 @@ static void wait_for_resolved(struct tracked_output **outs) case WIRE_ONCHAIND_SPEND_TO_US: case WIRE_ONCHAIND_SPEND_PENALTY: case WIRE_ONCHAIND_SPEND_HTLC_SUCCESS: + case WIRE_ONCHAIND_SPEND_HTLC_TIMEOUT: case WIRE_ONCHAIND_SPEND_FULFILL: break; } @@ -2099,10 +2082,10 @@ static size_t resolve_our_htlc_ourcommit(struct tracked_output *out, u8 **htlc_scripts) { struct bitcoin_tx *tx = NULL; - struct bitcoin_signature localsig; size_t i; + struct amount_sat fee; struct amount_msat htlc_amount; - u8 **witness; + const u8 *msg, *htlc_wscript; if (!amount_sat_to_msat(&htlc_amount, out->sat)) status_failed(STATUS_FAIL_INTERNAL_ERROR, @@ -2175,18 +2158,27 @@ static size_t resolve_our_htlc_ourcommit(struct tracked_output *out, ? "option_anchor_outputs" : ""); } - hsm_sign_local_htlc_tx(tx, htlc_scripts[matches[i]], &localsig); - - witness = bitcoin_witness_htlc_timeout_tx(tx, &localsig, - out->remote_htlc_sig, - htlc_scripts[matches[i]]); - - bitcoin_tx_input_set_witness(tx, 0, take(witness)); - - /* Steals tx onto out */ - propose_resolution_at_block(out, tx, htlcs[matches[i]].cltv_expiry, - OUR_HTLC_TIMEOUT_TX); + /* 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 = bitcoin_tx_compute_fee(tx); + msg = towire_onchaind_spend_htlc_timeout(NULL, + &out->outpoint, + out->sat, + fee, + htlcs[matches[i]].id, + htlcs[matches[i]].cltv_expiry, + commit_num, + out->remote_htlc_sig, + htlc_scripts[matches[i]], + htlc_wscript); + propose_resolution_to_master(out, take(msg), + /* nLocktime: we have to be *after* that block! */ + htlcs[matches[i]].cltv_expiry + 1, + OUR_HTLC_TIMEOUT_TX); return matches[i]; } diff --git a/onchaind/onchaind_wire.csv b/onchaind/onchaind_wire.csv index 386584e32..369e61e41 100644 --- a/onchaind/onchaind_wire.csv +++ b/onchaind/onchaind_wire.csv @@ -183,6 +183,20 @@ msgdata,onchaind_spend_fulfill,preimage,preimage, msgdata,onchaind_spend_fulfill,wscript_len,u32, msgdata,onchaind_spend_fulfill,wscript,u8,wscript_len +# We tell lightningd to create, sign and broadcast this htlc_timeout tx: +msgtype,onchaind_spend_htlc_timeout,5044 +msgdata,onchaind_spend_htlc_timeout,outpoint,bitcoin_outpoint, +msgdata,onchaind_spend_htlc_timeout,outpoint_amount,amount_sat, +msgdata,onchaind_spend_htlc_timeout,fee,amount_sat, +msgdata,onchaind_spend_htlc_timeout,htlc_id,u64, +msgdata,onchaind_spend_htlc_timeout,cltv_expiry,u32, +msgdata,onchaind_spend_htlc_timeout,commit_num,u64, +msgdata,onchaind_spend_htlc_timeout,remote_htlc_sig,bitcoin_signature, +msgdata,onchaind_spend_htlc_timeout,wscript_len,u32, +msgdata,onchaind_spend_htlc_timeout,wscript,u8,wscript_len +msgdata,onchaind_spend_htlc_timeout,htlc_wscript_len,u32, +msgdata,onchaind_spend_htlc_timeout,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 37b2135c7..eb4a692c4 100644 --- a/onchaind/test/run-grind_feerate-bug.c +++ b/onchaind/test/run-grind_feerate-bug.c @@ -11,6 +11,9 @@ int test_main(int argc, char *argv[]); #include "../onchaind.c" #undef main +#include "../onchaind_wiregen.c" +#include "wire/fromwire.c" +#include "wire/towire.c" /* AUTOGENERATED MOCKS START */ /* Generated stub for commit_number_obscurer */ @@ -27,68 +30,33 @@ bool derive_keyset(const struct pubkey *per_commitment_point UNNEEDED, bool option_static_remotekey UNNEEDED, struct keyset *keyset UNNEEDED) { fprintf(stderr, "derive_keyset called!\n"); abort(); } -/* Generated stub for fromwire */ -const u8 *fromwire(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, void *copy UNNEEDED, size_t n UNNEEDED) -{ fprintf(stderr, "fromwire called!\n"); abort(); } -/* Generated stub for fromwire_bool */ -bool fromwire_bool(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) -{ fprintf(stderr, "fromwire_bool called!\n"); abort(); } -/* Generated stub for fromwire_fail */ -void *fromwire_fail(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) -{ fprintf(stderr, "fromwire_fail called!\n"); abort(); } +/* Generated stub for fromwire_basepoints */ +void fromwire_basepoints(const u8 **ptr UNNEEDED, size_t *max UNNEEDED, + struct basepoints *b UNNEEDED) +{ fprintf(stderr, "fromwire_basepoints called!\n"); abort(); } +/* Generated stub for fromwire_chain_coin_mvt */ +void fromwire_chain_coin_mvt(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct chain_coin_mvt *mvt UNNEEDED) +{ fprintf(stderr, "fromwire_chain_coin_mvt called!\n"); abort(); } +/* Generated stub for fromwire_ext_key */ +void fromwire_ext_key(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct ext_key *bip32 UNNEEDED) +{ fprintf(stderr, "fromwire_ext_key called!\n"); abort(); } /* Generated stub for fromwire_hsmd_get_per_commitment_point_reply */ bool fromwire_hsmd_get_per_commitment_point_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct pubkey *per_commitment_point UNNEEDED, struct secret **old_commitment_secret UNNEEDED) { fprintf(stderr, "fromwire_hsmd_get_per_commitment_point_reply called!\n"); abort(); } -/* Generated stub for fromwire_onchaind_depth */ -bool fromwire_onchaind_depth(const void *p UNNEEDED, struct bitcoin_txid *txid UNNEEDED, u32 *depth UNNEEDED) -{ fprintf(stderr, "fromwire_onchaind_depth called!\n"); abort(); } -/* Generated stub for fromwire_onchaind_dev_memleak */ -bool fromwire_onchaind_dev_memleak(const void *p UNNEEDED) -{ fprintf(stderr, "fromwire_onchaind_dev_memleak called!\n"); abort(); } -/* Generated stub for fromwire_onchaind_htlcs */ -bool fromwire_onchaind_htlcs(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct htlc_stub **htlc UNNEEDED, bool **tell_if_missing UNNEEDED, bool **tell_immediately UNNEEDED) -{ fprintf(stderr, "fromwire_onchaind_htlcs called!\n"); abort(); } -/* Generated stub for fromwire_onchaind_init */ -bool fromwire_onchaind_init(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct shachain *shachain UNNEEDED, const struct chainparams **chainparams UNNEEDED, struct amount_sat *funding_amount_satoshi UNNEEDED, struct amount_msat *our_msat UNNEEDED, struct pubkey *old_remote_per_commitment_point UNNEEDED, struct pubkey *remote_per_commitment_point UNNEEDED, u32 *local_to_self_delay UNNEEDED, u32 *remote_to_self_delay UNNEEDED, u32 *delayed_to_us_feerate UNNEEDED, u32 *htlc_feerate UNNEEDED, u32 *penalty_feerate UNNEEDED, u32 *max_penalty_feerate UNNEEDED, struct amount_sat *local_dust_limit_satoshi UNNEEDED, struct bitcoin_txid *our_broadcast_txid UNNEEDED, u8 **local_scriptpubkey UNNEEDED, u8 **remote_scriptpubkey UNNEEDED, u32 *ourwallet_index UNNEEDED, struct ext_key *ourwallet_ext_key UNNEEDED, struct pubkey *ourwallet_pubkey UNNEEDED, enum side *opener UNNEEDED, struct basepoints *local_basepoints UNNEEDED, struct basepoints *remote_basepoints UNNEEDED, struct tx_parts **tx_parts UNNEEDED, u32 *locktime UNNEEDED, u32 *tx_blockheight UNNEEDED, u32 *reasonable_depth UNNEEDED, struct bitcoin_signature **htlc_signature UNNEEDED, u32 *min_possible_feerate UNNEEDED, u32 *max_possible_feerate UNNEEDED, struct pubkey **possible_remote_per_commit_point UNNEEDED, struct pubkey *local_funding_pubkey UNNEEDED, struct pubkey *remote_funding_pubkey UNNEEDED, u64 *local_static_remotekey_start UNNEEDED, u64 *remote_static_remotekey_start UNNEEDED, bool *option_anchor_outputs UNNEEDED, u32 *min_relay_feerate UNNEEDED) -{ fprintf(stderr, "fromwire_onchaind_init called!\n"); abort(); } -/* Generated stub for fromwire_onchaind_known_preimage */ -bool fromwire_onchaind_known_preimage(const void *p UNNEEDED, struct preimage *preimage UNNEEDED) -{ fprintf(stderr, "fromwire_onchaind_known_preimage called!\n"); abort(); } -/* Generated stub for fromwire_onchaind_spend_created */ -bool fromwire_onchaind_spend_created(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, bool *expect_to_succeed UNNEEDED, struct onchain_witness_element ***witness UNNEEDED) -{ fprintf(stderr, "fromwire_onchaind_spend_created called!\n"); abort(); } -/* Generated stub for fromwire_onchaind_spent */ -bool fromwire_onchaind_spent(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct tx_parts **tx UNNEEDED, u32 *input_num UNNEEDED, u32 *blockheight UNNEEDED) -{ fprintf(stderr, "fromwire_onchaind_spent called!\n"); abort(); } -/* Generated stub for fromwire_peektype */ -int fromwire_peektype(const u8 *cursor UNNEEDED) -{ fprintf(stderr, "fromwire_peektype called!\n"); abort(); } -/* Generated stub for fromwire_secp256k1_ecdsa_signature */ -void fromwire_secp256k1_ecdsa_signature(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, - secp256k1_ecdsa_signature *signature UNNEEDED) -{ fprintf(stderr, "fromwire_secp256k1_ecdsa_signature called!\n"); abort(); } -/* Generated stub for fromwire_sha256 */ -void fromwire_sha256(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct sha256 *sha256 UNNEEDED) -{ fprintf(stderr, "fromwire_sha256 called!\n"); abort(); } -/* Generated stub for fromwire_tal_arrn */ -u8 *fromwire_tal_arrn(const tal_t *ctx UNNEEDED, - const u8 **cursor UNNEEDED, size_t *max UNNEEDED, size_t num UNNEEDED) -{ fprintf(stderr, "fromwire_tal_arrn called!\n"); abort(); } -/* Generated stub for fromwire_u16 */ -u16 fromwire_u16(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) -{ fprintf(stderr, "fromwire_u16 called!\n"); abort(); } -/* 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 fromwire_u64 */ -u64 fromwire_u64(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) -{ fprintf(stderr, "fromwire_u64 called!\n"); abort(); } -/* Generated stub for fromwire_u8 */ -u8 fromwire_u8(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) -{ fprintf(stderr, "fromwire_u8 called!\n"); abort(); } -/* Generated stub for fromwire_u8_array */ -void fromwire_u8_array(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, u8 *arr UNNEEDED, size_t num UNNEEDED) -{ fprintf(stderr, "fromwire_u8_array called!\n"); abort(); } +/* Generated stub for fromwire_htlc_stub */ +void fromwire_htlc_stub(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, + struct htlc_stub *htlc_stub UNNEEDED) +{ fprintf(stderr, "fromwire_htlc_stub called!\n"); abort(); } +/* Generated stub for fromwire_shachain */ +void fromwire_shachain(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, + struct shachain *shachain UNNEEDED) +{ fprintf(stderr, "fromwire_shachain called!\n"); abort(); } +/* Generated stub for fromwire_side */ +enum side fromwire_side(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) +{ fprintf(stderr, "fromwire_side called!\n"); abort(); } +/* Generated stub for fromwire_wallet_tx_type */ +enum wallet_tx_type fromwire_wallet_tx_type(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) +{ fprintf(stderr, "fromwire_wallet_tx_type called!\n"); abort(); } /* Generated stub for htlc_offered_wscript */ u8 *htlc_offered_wscript(const tal_t *ctx UNNEEDED, const struct ripemd160 *ripemd UNNEEDED, @@ -207,9 +175,6 @@ enum mvt_tag *new_tag_arr(const tal_t *ctx UNNEEDED, enum mvt_tag tag UNNEEDED) /* Generated stub for notleak_ */ void *notleak_(void *ptr UNNEEDED, bool plus_children UNNEEDED) { fprintf(stderr, "notleak_ called!\n"); abort(); } -/* Generated stub for onchaind_wire_name */ -const char *onchaind_wire_name(int e UNNEEDED) -{ fprintf(stderr, "onchaind_wire_name called!\n"); abort(); } /* Generated stub for peer_billboard */ void peer_billboard(bool perm UNNEEDED, const char *fmt UNNEEDED, ...) { fprintf(stderr, "peer_billboard called!\n"); abort(); } @@ -234,91 +199,33 @@ u8 *to_self_wscript(const tal_t *ctx UNNEEDED, u32 csv UNNEEDED, const struct keyset *keyset UNNEEDED) { fprintf(stderr, "to_self_wscript called!\n"); abort(); } -/* Generated stub for towire */ -void towire(u8 **pptr UNNEEDED, const void *data UNNEEDED, size_t len UNNEEDED) -{ fprintf(stderr, "towire called!\n"); abort(); } -/* Generated stub for towire_bool */ -void towire_bool(u8 **pptr UNNEEDED, bool v UNNEEDED) -{ fprintf(stderr, "towire_bool called!\n"); abort(); } +/* Generated stub for towire_basepoints */ +void towire_basepoints(u8 **pptr UNNEEDED, const struct basepoints *b UNNEEDED) +{ fprintf(stderr, "towire_basepoints called!\n"); abort(); } +/* Generated stub for towire_chain_coin_mvt */ +void towire_chain_coin_mvt(u8 **pptr UNNEEDED, const struct chain_coin_mvt *mvt UNNEEDED) +{ fprintf(stderr, "towire_chain_coin_mvt called!\n"); abort(); } +/* Generated stub for towire_ext_key */ +void towire_ext_key(u8 **pptr UNNEEDED, const struct ext_key *bip32 UNNEEDED) +{ fprintf(stderr, "towire_ext_key called!\n"); abort(); } /* Generated stub for towire_hsmd_get_per_commitment_point */ u8 *towire_hsmd_get_per_commitment_point(const tal_t *ctx UNNEEDED, u64 n UNNEEDED) { fprintf(stderr, "towire_hsmd_get_per_commitment_point called!\n"); abort(); } -/* Generated stub for towire_hsmd_sign_penalty_to_us */ -u8 *towire_hsmd_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_hsmd_sign_penalty_to_us called!\n"); abort(); } /* Generated stub for towire_hsmd_sign_remote_htlc_to_us */ u8 *towire_hsmd_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, bool option_anchor_outputs UNNEEDED) { fprintf(stderr, "towire_hsmd_sign_remote_htlc_to_us called!\n"); abort(); } -/* Generated stub for towire_onchaind_add_utxo */ -u8 *towire_onchaind_add_utxo(const tal_t *ctx UNNEEDED, const struct bitcoin_outpoint *prev_out UNNEEDED, const struct pubkey *per_commit_point UNNEEDED, struct amount_sat value UNNEEDED, u32 blockheight UNNEEDED, const u8 *scriptpubkey UNNEEDED, u32 csv_lock UNNEEDED) -{ fprintf(stderr, "towire_onchaind_add_utxo called!\n"); abort(); } -/* Generated stub for towire_onchaind_all_irrevocably_resolved */ -u8 *towire_onchaind_all_irrevocably_resolved(const tal_t *ctx UNNEEDED) -{ fprintf(stderr, "towire_onchaind_all_irrevocably_resolved called!\n"); abort(); } -/* Generated stub for towire_onchaind_annotate_txin */ -u8 *towire_onchaind_annotate_txin(const tal_t *ctx UNNEEDED, const struct bitcoin_txid *txid UNNEEDED, u32 innum UNNEEDED, enum wallet_tx_type type UNNEEDED) -{ fprintf(stderr, "towire_onchaind_annotate_txin called!\n"); abort(); } -/* Generated stub for towire_onchaind_annotate_txout */ -u8 *towire_onchaind_annotate_txout(const tal_t *ctx UNNEEDED, const struct bitcoin_outpoint *outpoint UNNEEDED, enum wallet_tx_type type UNNEEDED) -{ fprintf(stderr, "towire_onchaind_annotate_txout called!\n"); abort(); } -/* Generated stub for towire_onchaind_broadcast_tx */ -u8 *towire_onchaind_broadcast_tx(const tal_t *ctx UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, bool is_rbf UNNEEDED) -{ fprintf(stderr, "towire_onchaind_broadcast_tx called!\n"); abort(); } -/* Generated stub for towire_onchaind_dev_memleak_reply */ -u8 *towire_onchaind_dev_memleak_reply(const tal_t *ctx UNNEEDED, bool leak UNNEEDED) -{ fprintf(stderr, "towire_onchaind_dev_memleak_reply called!\n"); abort(); } -/* Generated stub for towire_onchaind_extracted_preimage */ -u8 *towire_onchaind_extracted_preimage(const tal_t *ctx UNNEEDED, const struct preimage *preimage UNNEEDED) -{ fprintf(stderr, "towire_onchaind_extracted_preimage called!\n"); abort(); } -/* Generated stub for towire_onchaind_htlc_timeout */ -u8 *towire_onchaind_htlc_timeout(const tal_t *ctx UNNEEDED, const struct htlc_stub *htlc UNNEEDED) -{ fprintf(stderr, "towire_onchaind_htlc_timeout called!\n"); abort(); } -/* Generated stub for towire_onchaind_init_reply */ -u8 *towire_onchaind_init_reply(const tal_t *ctx UNNEEDED, u64 commit_num UNNEEDED) -{ fprintf(stderr, "towire_onchaind_init_reply called!\n"); abort(); } -/* Generated stub for towire_onchaind_missing_htlc_output */ -u8 *towire_onchaind_missing_htlc_output(const tal_t *ctx UNNEEDED, const struct htlc_stub *htlc UNNEEDED) -{ fprintf(stderr, "towire_onchaind_missing_htlc_output called!\n"); abort(); } -/* 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_fulfill */ -u8 *towire_onchaind_spend_fulfill(const tal_t *ctx UNNEEDED, const struct bitcoin_outpoint *outpoint UNNEEDED, struct amount_sat outpoint_amount UNNEEDED, u64 htlc_id UNNEEDED, const struct pubkey *remote_per_commitment_point UNNEEDED, const struct preimage *preimage UNNEEDED, const u8 *wscript UNNEEDED) -{ fprintf(stderr, "towire_onchaind_spend_fulfill 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(); } -/* Generated stub for towire_onchaind_spend_to_us */ -u8 *towire_onchaind_spend_to_us(const tal_t *ctx UNNEEDED, const struct bitcoin_outpoint *outpoint UNNEEDED, struct amount_sat outpoint_amount UNNEEDED, u32 minblock UNNEEDED, u64 commit_num UNNEEDED, const u8 *wscript UNNEEDED) -{ fprintf(stderr, "towire_onchaind_spend_to_us called!\n"); abort(); } -/* Generated stub for towire_onchaind_unwatch_tx */ -u8 *towire_onchaind_unwatch_tx(const tal_t *ctx UNNEEDED, const struct bitcoin_txid *txid UNNEEDED) -{ fprintf(stderr, "towire_onchaind_unwatch_tx called!\n"); abort(); } -/* Generated stub for towire_secp256k1_ecdsa_signature */ -void towire_secp256k1_ecdsa_signature(u8 **pptr UNNEEDED, - const secp256k1_ecdsa_signature *signature UNNEEDED) -{ fprintf(stderr, "towire_secp256k1_ecdsa_signature called!\n"); abort(); } -/* Generated stub for towire_sha256 */ -void towire_sha256(u8 **pptr UNNEEDED, const struct sha256 *sha256 UNNEEDED) -{ fprintf(stderr, "towire_sha256 called!\n"); abort(); } -/* Generated stub for towire_u16 */ -void towire_u16(u8 **pptr UNNEEDED, u16 v UNNEEDED) -{ fprintf(stderr, "towire_u16 called!\n"); abort(); } -/* Generated stub for towire_u32 */ -void towire_u32(u8 **pptr UNNEEDED, u32 v UNNEEDED) -{ fprintf(stderr, "towire_u32 called!\n"); abort(); } -/* Generated stub for towire_u64 */ -void towire_u64(u8 **pptr UNNEEDED, u64 v UNNEEDED) -{ fprintf(stderr, "towire_u64 called!\n"); abort(); } -/* Generated stub for towire_u8 */ -void towire_u8(u8 **pptr UNNEEDED, u8 v UNNEEDED) -{ fprintf(stderr, "towire_u8 called!\n"); abort(); } -/* Generated stub for towire_u8_array */ -void towire_u8_array(u8 **pptr UNNEEDED, const u8 *arr UNNEEDED, size_t num UNNEEDED) -{ fprintf(stderr, "towire_u8_array called!\n"); abort(); } +/* Generated stub for towire_htlc_stub */ +void towire_htlc_stub(u8 **pptr UNNEEDED, const struct htlc_stub *htlc_stub UNNEEDED) +{ fprintf(stderr, "towire_htlc_stub called!\n"); abort(); } +/* Generated stub for towire_shachain */ +void towire_shachain(u8 **pptr UNNEEDED, const struct shachain *shachain UNNEEDED) +{ fprintf(stderr, "towire_shachain called!\n"); abort(); } +/* Generated stub for towire_side */ +void towire_side(u8 **pptr UNNEEDED, const enum side side UNNEEDED) +{ fprintf(stderr, "towire_side called!\n"); abort(); } +/* Generated stub for towire_wallet_tx_type */ +void towire_wallet_tx_type(u8 **pptr UNNEEDED, const enum wallet_tx_type type UNNEEDED) +{ fprintf(stderr, "towire_wallet_tx_type called!\n"); abort(); } /* AUTOGENERATED MOCKS END */ #if DEVELOPER @@ -349,9 +256,9 @@ u8 *towire_hsmd_sign_local_htlc_tx(const tal_t *ctx UNNEEDED, u64 commit_num UNN return NULL; } -u8 *wire_sync_read(const tal_t *ctx UNNEEDED, int fd UNNEEDED) +u8 *wire_sync_read(const tal_t *ctx, int fd UNNEEDED) { - return (u8 *)ctx; + return towire_onchaind_spend_created(ctx, true, NULL); } bool wire_sync_write(int fd UNNEEDED, const void *msg TAKES) @@ -430,10 +337,14 @@ int main(int argc, char *argv[]) common_setup(argv[0]); chainparams = chainparams_for_network("bitcoin"); + queued_msgs = tal_arr(tmpctx, const u8 *, 0); htlcs[0].cltv_expiry = 585998; htlcs[1].cltv_expiry = 585998; htlcs[2].cltv_expiry = 586034; + htlcs[0].id = 0; + htlcs[1].id = 0; + htlcs[2].id = 0; htlc_scripts[0] = tal_hexdata(tmpctx, "76a914f454b1fe5b95428d6beec58ed3131a6ea611b2fa8763ac672103f83ca95b22920e71487736a7284696dd52443fd8f7ce683153ac31d1d1db7da67c820120876475527c21026ebaa1d08757b86110e40e3f4a081803eec694e23ec75ee0bfd753589df896e752ae67a9148dbcec4a5d782dd87588801607ea7dfc8874ffee88ac6868", strlen("76a914f454b1fe5b95428d6beec58ed3131a6ea611b2fa8763ac672103f83ca95b22920e71487736a7284696dd52443fd8f7ce683153ac31d1d1db7da67c820120876475527c21026ebaa1d08757b86110e40e3f4a081803eec694e23ec75ee0bfd753589df896e752ae67a9148dbcec4a5d782dd87588801607ea7dfc8874ffee88ac6868")); htlc_scripts[1] = tal_hexdata(tmpctx, "76a914f454b1fe5b95428d6beec58ed3131a6ea611b2fa8763ac672103f83ca95b22920e71487736a7284696dd52443fd8f7ce683153ac31d1d1db7da67c820120876475527c21026ebaa1d08757b86110e40e3f4a081803eec694e23ec75ee0bfd753589df896e752ae67a9148dbcec4a5d782dd87588801607ea7dfc8874ffee88ac6868", @@ -461,6 +372,10 @@ int main(int argc, char *argv[]) strlen("03f83ca95b22920e71487736a7284696dd52443fd8f7ce683153ac31d1d1db7da6"), &keys->other_htlc_key)) abort(); + /* resolve_our_htlc_ourcommit wants these too; set to anything valid. */ + keys->self_revocation_key + = keys->self_delayed_payment_key + = keys->other_htlc_key; min_possible_feerate = 10992; max_possible_feerate = 15370; diff --git a/onchaind/test/run-grind_feerate.c b/onchaind/test/run-grind_feerate.c index 608e251cb..15712fe3d 100644 --- a/onchaind/test/run-grind_feerate.c +++ b/onchaind/test/run-grind_feerate.c @@ -272,12 +272,6 @@ void towire_bool(u8 **pptr UNNEEDED, bool v UNNEEDED) /* Generated stub for towire_hsmd_get_per_commitment_point */ u8 *towire_hsmd_get_per_commitment_point(const tal_t *ctx UNNEEDED, u64 n UNNEEDED) { fprintf(stderr, "towire_hsmd_get_per_commitment_point called!\n"); abort(); } -/* Generated stub for towire_hsmd_sign_local_htlc_tx */ -u8 *towire_hsmd_sign_local_htlc_tx(const tal_t *ctx UNNEEDED, u64 commit_num UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED, bool option_anchor_outputs UNNEEDED) -{ fprintf(stderr, "towire_hsmd_sign_local_htlc_tx called!\n"); abort(); } -/* Generated stub for towire_hsmd_sign_penalty_to_us */ -u8 *towire_hsmd_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_hsmd_sign_penalty_to_us called!\n"); abort(); } /* Generated stub for towire_hsmd_sign_remote_htlc_to_us */ u8 *towire_hsmd_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, bool option_anchor_outputs UNNEEDED) { fprintf(stderr, "towire_hsmd_sign_remote_htlc_to_us called!\n"); abort(); } @@ -320,6 +314,9 @@ u8 *towire_onchaind_spend_fulfill(const tal_t *ctx UNNEEDED, const struct bitcoi /* 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_htlc_timeout */ +u8 *towire_onchaind_spend_htlc_timeout(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, u32 cltv_expiry UNNEEDED, u64 commit_num UNNEEDED, const struct bitcoin_signature *remote_htlc_sig UNNEEDED, const u8 *wscript UNNEEDED, const u8 *htlc_wscript UNNEEDED) +{ fprintf(stderr, "towire_onchaind_spend_htlc_timeout 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 42e64eaaf..ede7c56ef 100644 --- a/tests/test_closing.py +++ b/tests/test_closing.py @@ -1500,11 +1500,14 @@ 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_log('Propose handling OUR_UNILATERAL/OUR_HTLC by OUR_HTLC_TIMEOUT_TX .* after 16 blocks') - ((_, txid, blocks),) = l2.wait_for_onchaind_tx('OUR_HTLC_SUCCESS_TX', - 'OUR_UNILATERAL/THEIR_HTLC') + ((_, txid, blocks), (_, txid2, blocks2)) = \ + l2.wait_for_onchaind_tx('OUR_HTLC_SUCCESS_TX', + 'OUR_UNILATERAL/THEIR_HTLC', + 'OUR_HTLC_TIMEOUT_TX', + 'OUR_UNILATERAL/OUR_HTLC') assert blocks == 0 + assert blocks2 == 15 bitcoind.generate_block(1, wait_for_mempool=txid) ((_, txid, blocks),) = l2.wait_for_onchaind_tx('OUR_DELAYED_RETURN_TO_WALLET', @@ -1514,10 +1517,8 @@ def test_penalty_htlc_tx_timeout(node_factory, bitcoind, chainparams): # At depth 5, l2 reclaims both their DELAYED_OUTPUT_TO_US and their delayed output bitcoind.generate_block(4) bitcoind.generate_block(10, wait_for_mempool=2) - l2.wait_for_onchaind_broadcast('OUR_HTLC_TIMEOUT_TX', - 'OUR_UNILATERAL/OUR_HTLC') - bitcoind.generate_block(1, wait_for_mempool=1) + bitcoind.generate_block(1, wait_for_mempool=txid2) # l3 comes back up, sees cheat, penalizes l2 (revokes the htlc they've offered; # notes that they've successfully claimed to_local and the fulfilled htlc) @@ -2122,23 +2123,18 @@ def test_onchain_timeout(node_factory, bitcoind, executor): l1.daemon.wait_for_log(' to ONCHAIN') l2.daemon.wait_for_log(' to ONCHAIN') - # Wait for timeout. - needle = l1.daemon.logsearch_start - l1.daemon.wait_for_log('Propose handling OUR_UNILATERAL/OUR_HTLC by OUR_HTLC_TIMEOUT_TX .* after 6 blocks') - # Could happen any order. - l1.daemon.logsearch_start = needle - ((_, txid, blocks),) = l1.wait_for_onchaind_tx('OUR_DELAYED_RETURN_TO_WALLET', - 'OUR_UNILATERAL/DELAYED_OUTPUT_TO_US') - assert blocks == 4 + ((_, txid1, blocks1), (_, txid2, blocks2)) = \ + l1.wait_for_onchaind_tx('OUR_DELAYED_RETURN_TO_WALLET', + 'OUR_UNILATERAL/DELAYED_OUTPUT_TO_US', + 'OUR_HTLC_TIMEOUT_TX', + 'OUR_UNILATERAL/OUR_HTLC') + assert blocks1 == 4 + assert blocks2 == 5 bitcoind.generate_block(4) - - bitcoind.generate_block(1, wait_for_mempool=txid) - l1.wait_for_onchaind_broadcast('OUR_HTLC_TIMEOUT_TX', - 'OUR_UNILATERAL/OUR_HTLC') - - bitcoind.generate_block(1, wait_for_mempool=1) + bitcoind.generate_block(1, wait_for_mempool=txid1) + bitcoind.generate_block(1, wait_for_mempool=txid2) # After the first block it saw htlc_timeout_tx and planned this: ((_, txid, blocks),) = l1.wait_for_onchaind_tx('OUR_DELAYED_RETURN_TO_WALLET', 'OUR_HTLC_TIMEOUT_TX/DELAYED_OUTPUT_TO_US') @@ -3161,13 +3157,13 @@ def test_permfail_htlc_out(node_factory, bitcoind, executor): l2.daemon.wait_for_log(' to ONCHAIN') # Could happen any order - needle = l2.daemon.logsearch_start - l2.daemon.wait_for_log('Propose handling OUR_UNILATERAL/OUR_HTLC by OUR_HTLC_TIMEOUT_TX \\(.*\\) after 6 blocks') - - l2.daemon.logsearch_start = needle - ((_, txid2, blocks),) = l2.wait_for_onchaind_tx('OUR_DELAYED_RETURN_TO_WALLET', - 'OUR_UNILATERAL/DELAYED_OUTPUT_TO_US') - assert blocks == 4 + ((_, _, blocks1), (_, txid2, blocks2)) = \ + l2.wait_for_onchaind_tx('OUR_HTLC_TIMEOUT_TX', + 'OUR_UNILATERAL/OUR_HTLC', + 'OUR_DELAYED_RETURN_TO_WALLET', + 'OUR_UNILATERAL/DELAYED_OUTPUT_TO_US') + assert blocks1 == 5 + assert blocks2 == 4 l1.daemon.wait_for_log('Propose handling THEIR_UNILATERAL/THEIR_HTLC by THEIR_HTLC_TIMEOUT_TO_THEM \\(IGNORING\\) after 6 blocks') # l1 then gets preimage, uses it instead of ignoring diff --git a/tests/test_misc.py b/tests/test_misc.py index 2150391e0..e16d24bb1 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -357,15 +357,16 @@ def test_htlc_out_timeout(node_factory, bitcoind, executor): l2.daemon.wait_for_log(' to ONCHAIN') # L1 will timeout HTLC immediately - needle = l1.daemon.logsearch_start - l1.daemon.wait_for_log('Propose handling OUR_UNILATERAL/OUR_HTLC by OUR_HTLC_TIMEOUT_TX .* after 0 blocks') - l1.daemon.logsearch_start = needle - ((_, _, blocks),) = l1.wait_for_onchaind_tx('OUR_DELAYED_RETURN_TO_WALLET', - 'OUR_UNILATERAL/DELAYED_OUTPUT_TO_US') - assert blocks == 4 + ((_, _, blocks1), (_, txid, blocks2)) = \ + l1.wait_for_onchaind_tx('OUR_DELAYED_RETURN_TO_WALLET', + 'OUR_UNILATERAL/DELAYED_OUTPUT_TO_US', + 'OUR_HTLC_TIMEOUT_TX', + 'OUR_UNILATERAL/OUR_HTLC') + assert blocks1 == 4 + # We hit deadline (we give 1 block grace), then mined another. + assert blocks2 == -2 - l1.daemon.wait_for_log('sendrawtx exit 0') - bitcoind.generate_block(1) + bitcoind.generate_block(1, wait_for_mempool=txid) ((rawtx, txid, blocks),) = l1.wait_for_onchaind_tx('OUR_DELAYED_RETURN_TO_WALLET', 'OUR_HTLC_TIMEOUT_TX/DELAYED_OUTPUT_TO_US')