From 372040bbd5df1d66c63230dec84904f4e2247f34 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 21 Feb 2018 07:29:09 +1030 Subject: [PATCH] lightningd/onchain_control: routines to control onchaind (move from peer_control.c) Signed-off-by: Rusty Russell --- lightningd/Makefile | 1 + lightningd/onchain_control.c | 473 +++++++++++++++++++++++++++++++++++ lightningd/onchain_control.h | 16 ++ lightningd/peer_control.c | 464 +--------------------------------- wallet/test/run-wallet.c | 75 +----- 5 files changed, 498 insertions(+), 531 deletions(-) create mode 100644 lightningd/onchain_control.c create mode 100644 lightningd/onchain_control.h diff --git a/lightningd/Makefile b/lightningd/Makefile index f33efd0fd..b5bef5fe1 100644 --- a/lightningd/Makefile +++ b/lightningd/Makefile @@ -63,6 +63,7 @@ LIGHTNINGD_SRC := \ lightningd/log.c \ lightningd/log_status.c \ lightningd/netaddress.c \ + lightningd/onchain_control.c \ lightningd/opening_control.c \ lightningd/opt_time.c \ lightningd/options.c \ diff --git a/lightningd/onchain_control.c b/lightningd/onchain_control.c new file mode 100644 index 000000000..eec615203 --- /dev/null +++ b/lightningd/onchain_control.c @@ -0,0 +1,473 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* We dump all the known preimages when onchaind starts up. */ +static void onchaind_tell_fulfill(struct channel *channel) +{ + struct htlc_in_map_iter ini; + struct htlc_in *hin; + u8 *msg; + struct lightningd *ld = channel->peer->ld; + + for (hin = htlc_in_map_first(&ld->htlcs_in, &ini); + hin; + hin = htlc_in_map_next(&ld->htlcs_in, &ini)) { + if (hin->key.channel != channel) + continue; + + /* BOLT #5: + * + * If the node receives (or already knows) a payment preimage + * for an unresolved HTLC output it was offered for which it + * has committed to an outgoing HTLC, it MUST *resolve* the + * output by spending it. Otherwise, if the other node is not + * irrevocably committed to the HTLC, it MUST NOT *resolve* + * the output by spending it. + */ + + /* We only set preimage once it's irrevocably committed, and + * we spend even if we don't have an outgoing HTLC (eg. local + * payment complete) */ + if (!hin->preimage) + continue; + + msg = towire_onchain_known_preimage(channel, hin->preimage); + subd_send_msg(channel->owner, take(msg)); + } +} + +static void handle_onchain_init_reply(struct channel *channel, const u8 *msg) +{ + u8 state; + + if (!fromwire_onchain_init_reply(msg, NULL, &state)) { + channel_internal_error(channel, "Invalid onchain_init_reply"); + return; + } + + if (!channel_state_on_chain(state)) { + channel_internal_error(channel, + "Invalid onchain_init_reply state %u (%s)", + state, channel_state_str(state)); + return; + } + + channel_set_state(channel, FUNDING_SPEND_SEEN, state); + + /* Tell it about any preimages we know. */ + onchaind_tell_fulfill(channel); +} + +static enum watch_result onchain_tx_watched(struct channel *channel, + const struct bitcoin_tx *tx, + unsigned int depth, + void *unused) +{ + u8 *msg; + struct bitcoin_txid txid; + + if (depth == 0) { + log_unusual(channel->log, "Chain reorganization!"); + channel_set_owner(channel, NULL); + + /* FIXME! + topology_rescan(peer->ld->topology, peer->funding_txid); + */ + + /* We will most likely be freed, so this is a noop */ + return KEEP_WATCHING; + } + + bitcoin_txid(tx, &txid); + msg = towire_onchain_depth(channel, &txid, depth); + subd_send_msg(channel->owner, take(msg)); + return KEEP_WATCHING; +} + +static void watch_tx_and_outputs(struct channel *channel, + const struct bitcoin_tx *tx); + +static enum watch_result onchain_txo_watched(struct channel *channel, + const struct bitcoin_tx *tx, + size_t input_num, + const struct block *block, + void *unused) +{ + u8 *msg; + + watch_tx_and_outputs(channel, tx); + + msg = towire_onchain_spent(channel, tx, input_num, block->height); + subd_send_msg(channel->owner, take(msg)); + + /* We don't need to keep watching: If this output is double-spent + * (reorg), we'll get a zero depth cb to onchain_tx_watched, and + * restart onchaind. */ + return DELETE_WATCH; +} + +/* To avoid races, we watch the tx and all outputs. */ +static void watch_tx_and_outputs(struct channel *channel, + const struct bitcoin_tx *tx) +{ + struct bitcoin_txid txid; + struct txwatch *txw; + struct lightningd *ld = channel->peer->ld; + + bitcoin_txid(tx, &txid); + + /* Make txwatch a parent of txo watches, so we can unwatch together. */ + txw = watch_tx(channel->owner, ld->topology, channel, tx, + onchain_tx_watched, NULL); + + for (size_t i = 0; i < tal_count(tx->output); i++) + watch_txo(txw, ld->topology, channel, &txid, i, + onchain_txo_watched, NULL); +} + +static void handle_onchain_broadcast_tx(struct channel *channel, const u8 *msg) +{ + struct bitcoin_tx *tx; + + if (!fromwire_onchain_broadcast_tx(msg, msg, NULL, &tx)) { + channel_internal_error(channel, "Invalid onchain_broadcast_tx"); + return; + } + + /* We don't really care if it fails, we'll respond via watch. */ + broadcast_tx(channel->peer->ld->topology, channel, tx, NULL); +} + +static void handle_onchain_unwatch_tx(struct channel *channel, const u8 *msg) +{ + struct bitcoin_txid txid; + struct txwatch *txw; + + if (!fromwire_onchain_unwatch_tx(msg, NULL, &txid)) { + channel_internal_error(channel, "Invalid onchain_unwatch_tx"); + return; + } + + /* Frees the txo watches, too: see watch_tx_and_outputs() */ + txw = find_txwatch(channel->peer->ld->topology, &txid, channel); + if (!txw) + log_unusual(channel->log, "Can't unwatch txid %s", + type_to_string(ltmp, struct bitcoin_txid, &txid)); + tal_free(txw); +} + +static void handle_extracted_preimage(struct channel *channel, const u8 *msg) +{ + struct preimage preimage; + + if (!fromwire_onchain_extracted_preimage(msg, NULL, &preimage)) { + channel_internal_error(channel, "Invalid extracted_preimage"); + return; + } + + onchain_fulfilled_htlc(channel, &preimage); +} + +static void handle_missing_htlc_output(struct channel *channel, const u8 *msg) +{ + struct htlc_stub htlc; + + if (!fromwire_onchain_missing_htlc_output(msg, NULL, &htlc)) { + channel_internal_error(channel, "Invalid missing_htlc_output"); + return; + } + + /* BOLT #5: + * + * For any committed HTLC which does not have an output in this + * commitment transaction, the node MUST fail the corresponding + * incoming HTLC (if any) once the commitment transaction has reached + * reasonable depth, and MAY fail it sooner if no valid commitment + * transaction contains an output corresponding to the HTLC. + */ + onchain_failed_our_htlc(channel, &htlc, "missing in commitment tx"); +} + +static void handle_onchain_htlc_timeout(struct channel *channel, const u8 *msg) +{ + struct htlc_stub htlc; + + if (!fromwire_onchain_htlc_timeout(msg, NULL, &htlc)) { + channel_internal_error(channel, "Invalid onchain_htlc_timeout"); + return; + } + + /* BOLT #5: + * + * If the HTLC output has *timed out* and not been *resolved*, the node + * MUST *resolve* the output and MUST fail the corresponding incoming + * HTLC (if any) once the resolving transaction has reached reasonable + * depth. + */ + onchain_failed_our_htlc(channel, &htlc, "timed out"); +} + +static void handle_irrevocably_resolved(struct channel *channel, const u8 *msg) +{ + /* FIXME: Implement check_htlcs to ensure no dangling hout->in ptrs! */ + free_htlcs(channel->peer->ld, channel); + + log_info(channel->log, "onchaind complete, forgetting peer"); + + /* This will also free onchaind. */ + delete_channel(channel, "onchaind complete, forgetting peer"); +} + +/** + * onchain_add_utxo -- onchaind is telling us about an UTXO we own + */ +static void onchain_add_utxo(struct channel *channel, const u8 *msg) +{ + struct utxo *u = tal(msg, struct utxo); + u->close_info = tal(u, struct unilateral_close_info); + + u->is_p2sh = true; + u->keyindex = 0; + u->status = output_state_available; + u->close_info->channel_id = channel->dbid; + u->close_info->peer_id = channel->peer->id; + + if (!fromwire_onchain_add_utxo(msg, NULL, &u->txid, &u->outnum, + &u->close_info->commitment_point, + &u->amount)) { + fatal("onchaind gave invalid add_utxo message: %s", tal_hex(msg, msg)); + } + + + wallet_add_utxo(channel->peer->ld->wallet, u, p2wpkh); +} + +static unsigned int onchain_msg(struct subd *sd, const u8 *msg, const int *fds) +{ + enum onchain_wire_type t = fromwire_peektype(msg); + + switch (t) { + case WIRE_ONCHAIN_INIT_REPLY: + handle_onchain_init_reply(sd->channel, msg); + break; + + case WIRE_ONCHAIN_BROADCAST_TX: + handle_onchain_broadcast_tx(sd->channel, msg); + break; + + case WIRE_ONCHAIN_UNWATCH_TX: + handle_onchain_unwatch_tx(sd->channel, msg); + break; + + case WIRE_ONCHAIN_EXTRACTED_PREIMAGE: + handle_extracted_preimage(sd->channel, msg); + break; + + case WIRE_ONCHAIN_MISSING_HTLC_OUTPUT: + handle_missing_htlc_output(sd->channel, msg); + break; + + case WIRE_ONCHAIN_HTLC_TIMEOUT: + handle_onchain_htlc_timeout(sd->channel, msg); + break; + + case WIRE_ONCHAIN_ALL_IRREVOCABLY_RESOLVED: + handle_irrevocably_resolved(sd->channel, msg); + break; + + case WIRE_ONCHAIN_ADD_UTXO: + onchain_add_utxo(sd->channel, msg); + break; + + /* We send these, not receive them */ + case WIRE_ONCHAIN_INIT: + case WIRE_ONCHAIN_SPENT: + case WIRE_ONCHAIN_DEPTH: + case WIRE_ONCHAIN_HTLC: + case WIRE_ONCHAIN_KNOWN_PREIMAGE: + break; + } + + return 0; +} + +/* If we want to know if this HTLC is missing, return depth. */ +static bool tell_if_missing(const struct channel *channel, + struct htlc_stub *stub, + bool *tell_immediate) +{ + struct htlc_out *hout; + + /* Keep valgrind happy. */ + *tell_immediate = false; + + /* Is it a current HTLC? */ + hout = find_htlc_out_by_ripemd(channel, &stub->ripemd); + if (!hout) + return false; + + /* BOLT #5: + * + * For any committed HTLC which does not have an output in this + * commitment transaction, the node MUST fail the corresponding + * incoming HTLC (if any) once the commitment transaction has reached + * reasonable depth, and MAY fail it sooner if no valid commitment + * transaction contains an output corresponding to the HTLC. + */ + if (hout->hstate >= RCVD_ADD_REVOCATION + && hout->hstate < SENT_REMOVE_REVOCATION) + *tell_immediate = true; + + log_debug(channel->log, + "We want to know if htlc %"PRIu64" is missing (%s)", + hout->key.id, *tell_immediate ? "immediate" : "later"); + return true; +} + +/* Only error onchaind can get is if it dies. */ +static void onchain_error(struct channel *channel, + int peer_fd, int gossip_fd, + const struct crypto_state *cs, + u64 gossip_index, + const struct channel_id *channel_id, + const char *desc, + const u8 *err_for_them) +{ + /* FIXME: re-launch? */ + log_broken(channel->log, "%s", desc); +} + +/* With a reorg, this can get called multiple times; each time we'll kill + * onchaind (like any other owner), and restart */ +enum watch_result funding_spent(struct channel *channel, + const struct bitcoin_tx *tx, + size_t input_num, + const struct block *block, + void *unused) +{ + u8 *msg, *scriptpubkey; + struct bitcoin_txid our_last_txid; + s64 keyindex; + struct pubkey ourkey; + struct htlc_stub *stubs; + const tal_t *tmpctx = tal_tmpctx(channel); + struct lightningd *ld = channel->peer->ld; + + channel_fail_permanent(channel, "Funding transaction spent"); + + /* We could come from almost any state. */ + channel_set_state(channel, channel->state, FUNDING_SPEND_SEEN); + + channel_set_owner(channel, new_channel_subd(ld, + "lightning_onchaind", + channel, + channel->log, + onchain_wire_type_name, + onchain_msg, + onchain_error, + NULL)); + + if (!channel->owner) { + log_broken(channel->log, "Could not subdaemon onchain: %s", + strerror(errno)); + tal_free(tmpctx); + return KEEP_WATCHING; + } + + stubs = wallet_htlc_stubs(tmpctx, ld->wallet, channel); + if (!stubs) { + log_broken(channel->log, "Could not load htlc_stubs"); + tal_free(tmpctx); + return KEEP_WATCHING; + } + + /* We re-use this key to send other outputs to. */ + if (channel->local_shutdown_idx >= 0) + keyindex = channel->local_shutdown_idx; + else { + keyindex = wallet_get_newindex(ld); + if (keyindex < 0) { + log_broken(channel->log, "Could not get keyindex"); + tal_free(tmpctx); + return KEEP_WATCHING; + } + } + scriptpubkey = p2wpkh_for_keyidx(tmpctx, ld, keyindex); + if (!scriptpubkey) { + channel_internal_error(channel, + "Can't get shutdown script %"PRIu64, + keyindex); + tal_free(tmpctx); + return DELETE_WATCH; + } + txfilter_add_scriptpubkey(ld->owned_txfilter, scriptpubkey); + + if (!bip32_pubkey(ld->wallet->bip32_base, &ourkey, keyindex)) { + channel_internal_error(channel, + "Can't get shutdown key %"PRIu64, + keyindex); + tal_free(tmpctx); + return DELETE_WATCH; + } + + /* This could be a mutual close, but it doesn't matter. */ + bitcoin_txid(channel->last_tx, &our_last_txid); + + msg = towire_onchain_init(channel, + &channel->seed, &channel->their_shachain.chain, + channel->funding_satoshi, + &channel->channel_info.old_remote_per_commit, + &channel->channel_info.remote_per_commit, + /* BOLT #2: + * `to_self_delay` is the number of blocks + * that the other nodes to-self outputs + * must be delayed */ + /* So, these are reversed: they specify ours, + * we specify theirs. */ + channel->channel_info.their_config.to_self_delay, + channel->our_config.to_self_delay, + get_feerate(ld->topology, FEERATE_NORMAL), + channel->our_config.dust_limit_satoshis, + &channel->channel_info.theirbase.revocation, + &our_last_txid, + scriptpubkey, + channel->remote_shutdown_scriptpubkey, + &ourkey, + channel->funder, + &channel->channel_info.theirbase.payment, + &channel->channel_info.theirbase.htlc, + &channel->channel_info.theirbase.delayed_payment, + tx, + block->height, + /* FIXME: config for 'reasonable depth' */ + 3, + channel->last_htlc_sigs, + tal_count(stubs)); + subd_send_msg(channel->owner, take(msg)); + + /* FIXME: Don't queue all at once, use an empty cb... */ + for (size_t i = 0; i < tal_count(stubs); i++) { + bool tell_immediate; + bool tell = tell_if_missing(channel, &stubs[i], &tell_immediate); + msg = towire_onchain_htlc(channel, &stubs[i], + tell, tell_immediate); + subd_send_msg(channel->owner, take(msg)); + } + + watch_tx_and_outputs(channel, tx); + + tal_free(tmpctx); + /* We keep watching until peer finally deleted, for reorgs. */ + return KEEP_WATCHING; +} + diff --git a/lightningd/onchain_control.h b/lightningd/onchain_control.h new file mode 100644 index 000000000..f1611c3a5 --- /dev/null +++ b/lightningd/onchain_control.h @@ -0,0 +1,16 @@ +#ifndef LIGHTNING_LIGHTNINGD_ONCHAIN_CONTROL_H +#define LIGHTNING_LIGHTNINGD_ONCHAIN_CONTROL_H +#include "config.h" +#include + +struct channel; +struct bitcoin_tx; +struct block; + +enum watch_result funding_spent(struct channel *channel, + const struct bitcoin_tx *tx, + size_t input_num, + const struct block *block, + void *unused); + +#endif /* LIGHTNING_LIGHTNINGD_ONCHAIN_CONTROL_H */ diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 59080b510..87f83e15e 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -34,11 +34,10 @@ #include #include #include +#include #include #include #include -#include -#include #include #include #include @@ -660,213 +659,6 @@ static enum watch_result funding_announce_cb(struct channel *channel, return DELETE_WATCH; } - -/* We dump all the known preimages when onchaind starts up. */ -static void onchaind_tell_fulfill(struct channel *channel) -{ - struct htlc_in_map_iter ini; - struct htlc_in *hin; - u8 *msg; - struct lightningd *ld = channel->peer->ld; - - for (hin = htlc_in_map_first(&ld->htlcs_in, &ini); - hin; - hin = htlc_in_map_next(&ld->htlcs_in, &ini)) { - if (hin->key.channel != channel) - continue; - - /* BOLT #5: - * - * If the node receives (or already knows) a payment preimage - * for an unresolved HTLC output it was offered for which it - * has committed to an outgoing HTLC, it MUST *resolve* the - * output by spending it. Otherwise, if the other node is not - * irrevocably committed to the HTLC, it MUST NOT *resolve* - * the output by spending it. - */ - - /* We only set preimage once it's irrevocably committed, and - * we spend even if we don't have an outgoing HTLC (eg. local - * payment complete) */ - if (!hin->preimage) - continue; - - msg = towire_onchain_known_preimage(channel, hin->preimage); - subd_send_msg(channel->owner, take(msg)); - } -} - -static void handle_onchain_init_reply(struct channel *channel, const u8 *msg) -{ - u8 state; - - if (!fromwire_onchain_init_reply(msg, NULL, &state)) { - channel_internal_error(channel, "Invalid onchain_init_reply"); - return; - } - - if (!channel_state_on_chain(state)) { - channel_internal_error(channel, - "Invalid onchain_init_reply state %u (%s)", - state, channel_state_str(state)); - return; - } - - channel_set_state(channel, FUNDING_SPEND_SEEN, state); - - /* Tell it about any preimages we know. */ - onchaind_tell_fulfill(channel); -} - -static enum watch_result onchain_tx_watched(struct channel *channel, - const struct bitcoin_tx *tx, - unsigned int depth, - void *unused) -{ - u8 *msg; - struct bitcoin_txid txid; - - if (depth == 0) { - log_unusual(channel->log, "Chain reorganization!"); - channel_set_owner(channel, NULL); - - /* FIXME! - topology_rescan(peer->ld->topology, peer->funding_txid); - */ - - /* We will most likely be freed, so this is a noop */ - return KEEP_WATCHING; - } - - bitcoin_txid(tx, &txid); - msg = towire_onchain_depth(channel, &txid, depth); - subd_send_msg(channel->owner, take(msg)); - return KEEP_WATCHING; -} - -static void watch_tx_and_outputs(struct channel *channel, - const struct bitcoin_tx *tx); - -static enum watch_result onchain_txo_watched(struct channel *channel, - const struct bitcoin_tx *tx, - size_t input_num, - const struct block *block, - void *unused) -{ - u8 *msg; - - watch_tx_and_outputs(channel, tx); - - msg = towire_onchain_spent(channel, tx, input_num, block->height); - subd_send_msg(channel->owner, take(msg)); - - /* We don't need to keep watching: If this output is double-spent - * (reorg), we'll get a zero depth cb to onchain_tx_watched, and - * restart onchaind. */ - return DELETE_WATCH; -} - -/* To avoid races, we watch the tx and all outputs. */ -static void watch_tx_and_outputs(struct channel *channel, - const struct bitcoin_tx *tx) -{ - struct bitcoin_txid txid; - struct txwatch *txw; - struct lightningd *ld = channel->peer->ld; - - bitcoin_txid(tx, &txid); - - /* Make txwatch a parent of txo watches, so we can unwatch together. */ - txw = watch_tx(channel->owner, ld->topology, channel, tx, - onchain_tx_watched, NULL); - - for (size_t i = 0; i < tal_count(tx->output); i++) - watch_txo(txw, ld->topology, channel, &txid, i, - onchain_txo_watched, NULL); -} - -static void handle_onchain_broadcast_tx(struct channel *channel, const u8 *msg) -{ - struct bitcoin_tx *tx; - - if (!fromwire_onchain_broadcast_tx(msg, msg, NULL, &tx)) { - channel_internal_error(channel, "Invalid onchain_broadcast_tx"); - return; - } - - /* We don't really care if it fails, we'll respond via watch. */ - broadcast_tx(channel->peer->ld->topology, channel, tx, NULL); -} - -static void handle_onchain_unwatch_tx(struct channel *channel, const u8 *msg) -{ - struct bitcoin_txid txid; - struct txwatch *txw; - - if (!fromwire_onchain_unwatch_tx(msg, NULL, &txid)) { - channel_internal_error(channel, "Invalid onchain_unwatch_tx"); - return; - } - - /* Frees the txo watches, too: see watch_tx_and_outputs() */ - txw = find_txwatch(channel->peer->ld->topology, &txid, channel); - if (!txw) - log_unusual(channel->log, "Can't unwatch txid %s", - type_to_string(ltmp, struct bitcoin_txid, &txid)); - tal_free(txw); -} - -static void handle_extracted_preimage(struct channel *channel, const u8 *msg) -{ - struct preimage preimage; - - if (!fromwire_onchain_extracted_preimage(msg, NULL, &preimage)) { - channel_internal_error(channel, "Invalid extracted_preimage"); - return; - } - - onchain_fulfilled_htlc(channel, &preimage); -} - -static void handle_missing_htlc_output(struct channel *channel, const u8 *msg) -{ - struct htlc_stub htlc; - - if (!fromwire_onchain_missing_htlc_output(msg, NULL, &htlc)) { - channel_internal_error(channel, "Invalid missing_htlc_output"); - return; - } - - /* BOLT #5: - * - * For any committed HTLC which does not have an output in this - * commitment transaction, the node MUST fail the corresponding - * incoming HTLC (if any) once the commitment transaction has reached - * reasonable depth, and MAY fail it sooner if no valid commitment - * transaction contains an output corresponding to the HTLC. - */ - onchain_failed_our_htlc(channel, &htlc, "missing in commitment tx"); -} - -static void handle_onchain_htlc_timeout(struct channel *channel, const u8 *msg) -{ - struct htlc_stub htlc; - - if (!fromwire_onchain_htlc_timeout(msg, NULL, &htlc)) { - channel_internal_error(channel, "Invalid onchain_htlc_timeout"); - return; - } - - /* BOLT #5: - * - * If the HTLC output has *timed out* and not been *resolved*, the node - * MUST *resolve* the output and MUST fail the corresponding incoming - * HTLC (if any) once the resolving transaction has reached reasonable - * depth. - */ - onchain_failed_our_htlc(channel, &htlc, "timed out"); -} - /* If channel is NULL, free them all (for shutdown) */ void free_htlcs(struct lightningd *ld, const struct channel *channel) { @@ -901,90 +693,6 @@ void free_htlcs(struct lightningd *ld, const struct channel *channel) } while (deleted); } -static void handle_irrevocably_resolved(struct channel *channel, const u8 *msg) -{ - /* FIXME: Implement check_htlcs to ensure no dangling hout->in ptrs! */ - free_htlcs(channel->peer->ld, channel); - - log_info(channel->log, "onchaind complete, forgetting peer"); - - /* This will also free onchaind. */ - delete_channel(channel, "onchaind complete, forgetting peer"); -} - -/** - * onchain_add_utxo -- onchaind is telling us about an UTXO we own - */ -static void onchain_add_utxo(struct channel *channel, const u8 *msg) -{ - struct utxo *u = tal(msg, struct utxo); - u->close_info = tal(u, struct unilateral_close_info); - - u->is_p2sh = true; - u->keyindex = 0; - u->status = output_state_available; - u->close_info->channel_id = channel->dbid; - u->close_info->peer_id = channel->peer->id; - - if (!fromwire_onchain_add_utxo(msg, NULL, &u->txid, &u->outnum, - &u->close_info->commitment_point, - &u->amount)) { - fatal("onchaind gave invalid add_utxo message: %s", tal_hex(msg, msg)); - } - - - wallet_add_utxo(channel->peer->ld->wallet, u, p2wpkh); -} - -static unsigned int onchain_msg(struct subd *sd, const u8 *msg, const int *fds) -{ - enum onchain_wire_type t = fromwire_peektype(msg); - - switch (t) { - case WIRE_ONCHAIN_INIT_REPLY: - handle_onchain_init_reply(sd->channel, msg); - break; - - case WIRE_ONCHAIN_BROADCAST_TX: - handle_onchain_broadcast_tx(sd->channel, msg); - break; - - case WIRE_ONCHAIN_UNWATCH_TX: - handle_onchain_unwatch_tx(sd->channel, msg); - break; - - case WIRE_ONCHAIN_EXTRACTED_PREIMAGE: - handle_extracted_preimage(sd->channel, msg); - break; - - case WIRE_ONCHAIN_MISSING_HTLC_OUTPUT: - handle_missing_htlc_output(sd->channel, msg); - break; - - case WIRE_ONCHAIN_HTLC_TIMEOUT: - handle_onchain_htlc_timeout(sd->channel, msg); - break; - - case WIRE_ONCHAIN_ALL_IRREVOCABLY_RESOLVED: - handle_irrevocably_resolved(sd->channel, msg); - break; - - case WIRE_ONCHAIN_ADD_UTXO: - onchain_add_utxo(sd->channel, msg); - break; - - /* We send these, not receive them */ - case WIRE_ONCHAIN_INIT: - case WIRE_ONCHAIN_SPENT: - case WIRE_ONCHAIN_DEPTH: - case WIRE_ONCHAIN_HTLC: - case WIRE_ONCHAIN_KNOWN_PREIMAGE: - break; - } - - return 0; -} - u8 *p2wpkh_for_keyidx(const tal_t *ctx, struct lightningd *ld, u64 keyidx) { struct pubkey shutdownkey; @@ -995,176 +703,6 @@ u8 *p2wpkh_for_keyidx(const tal_t *ctx, struct lightningd *ld, u64 keyidx) return scriptpubkey_p2wpkh(ctx, &shutdownkey); } -/* If we want to know if this HTLC is missing, return depth. */ -static bool tell_if_missing(const struct channel *channel, - struct htlc_stub *stub, - bool *tell_immediate) -{ - struct htlc_out *hout; - - /* Keep valgrind happy. */ - *tell_immediate = false; - - /* Is it a current HTLC? */ - hout = find_htlc_out_by_ripemd(channel, &stub->ripemd); - if (!hout) - return false; - - /* BOLT #5: - * - * For any committed HTLC which does not have an output in this - * commitment transaction, the node MUST fail the corresponding - * incoming HTLC (if any) once the commitment transaction has reached - * reasonable depth, and MAY fail it sooner if no valid commitment - * transaction contains an output corresponding to the HTLC. - */ - if (hout->hstate >= RCVD_ADD_REVOCATION - && hout->hstate < SENT_REMOVE_REVOCATION) - *tell_immediate = true; - - log_debug(channel->log, - "We want to know if htlc %"PRIu64" is missing (%s)", - hout->key.id, *tell_immediate ? "immediate" : "later"); - return true; -} - -/* Only error onchaind can get is if it dies. */ -static void onchain_error(struct channel *channel, - int peer_fd, int gossip_fd, - const struct crypto_state *cs, - u64 gossip_index, - const struct channel_id *channel_id, - const char *desc, - const u8 *err_for_them) -{ - /* FIXME: re-launch? */ - log_broken(channel->log, "%s", desc); -} - -/* With a reorg, this can get called multiple times; each time we'll kill - * onchaind (like any other owner), and restart */ -static enum watch_result funding_spent(struct channel *channel, - const struct bitcoin_tx *tx, - size_t input_num, - const struct block *block, - void *unused) -{ - u8 *msg, *scriptpubkey; - struct bitcoin_txid our_last_txid; - s64 keyindex; - struct pubkey ourkey; - struct htlc_stub *stubs; - const tal_t *tmpctx = tal_tmpctx(channel); - struct lightningd *ld = channel->peer->ld; - - channel_fail_permanent(channel, "Funding transaction spent"); - - /* We could come from almost any state. */ - channel_set_state(channel, channel->state, FUNDING_SPEND_SEEN); - - channel_set_owner(channel, new_channel_subd(ld, - "lightning_onchaind", - channel, - channel->log, - onchain_wire_type_name, - onchain_msg, - onchain_error, - NULL)); - - if (!channel->owner) { - log_broken(channel->log, "Could not subdaemon onchain: %s", - strerror(errno)); - tal_free(tmpctx); - return KEEP_WATCHING; - } - - stubs = wallet_htlc_stubs(tmpctx, ld->wallet, channel); - if (!stubs) { - log_broken(channel->log, "Could not load htlc_stubs"); - tal_free(tmpctx); - return KEEP_WATCHING; - } - - /* We re-use this key to send other outputs to. */ - if (channel->local_shutdown_idx >= 0) - keyindex = channel->local_shutdown_idx; - else { - keyindex = wallet_get_newindex(ld); - if (keyindex < 0) { - log_broken(channel->log, "Could not get keyindex"); - tal_free(tmpctx); - return KEEP_WATCHING; - } - } - scriptpubkey = p2wpkh_for_keyidx(tmpctx, ld, keyindex); - if (!scriptpubkey) { - channel_internal_error(channel, - "Can't get shutdown script %"PRIu64, - keyindex); - tal_free(tmpctx); - return DELETE_WATCH; - } - txfilter_add_scriptpubkey(ld->owned_txfilter, scriptpubkey); - - if (!bip32_pubkey(ld->wallet->bip32_base, &ourkey, keyindex)) { - channel_internal_error(channel, - "Can't get shutdown key %"PRIu64, - keyindex); - tal_free(tmpctx); - return DELETE_WATCH; - } - - /* This could be a mutual close, but it doesn't matter. */ - bitcoin_txid(channel->last_tx, &our_last_txid); - - msg = towire_onchain_init(channel, - &channel->seed, &channel->their_shachain.chain, - channel->funding_satoshi, - &channel->channel_info.old_remote_per_commit, - &channel->channel_info.remote_per_commit, - /* BOLT #2: - * `to_self_delay` is the number of blocks - * that the other nodes to-self outputs - * must be delayed */ - /* So, these are reversed: they specify ours, - * we specify theirs. */ - channel->channel_info.their_config.to_self_delay, - channel->our_config.to_self_delay, - get_feerate(ld->topology, FEERATE_NORMAL), - channel->our_config.dust_limit_satoshis, - &channel->channel_info.theirbase.revocation, - &our_last_txid, - scriptpubkey, - channel->remote_shutdown_scriptpubkey, - &ourkey, - channel->funder, - &channel->channel_info.theirbase.payment, - &channel->channel_info.theirbase.htlc, - &channel->channel_info.theirbase.delayed_payment, - tx, - block->height, - /* FIXME: config for 'reasonable depth' */ - 3, - channel->last_htlc_sigs, - tal_count(stubs)); - subd_send_msg(channel->owner, take(msg)); - - /* FIXME: Don't queue all at once, use an empty cb... */ - for (size_t i = 0; i < tal_count(stubs); i++) { - bool tell_immediate; - bool tell = tell_if_missing(channel, &stubs[i], &tell_immediate); - msg = towire_onchain_htlc(channel, &stubs[i], - tell, tell_immediate); - subd_send_msg(channel->owner, take(msg)); - } - - watch_tx_and_outputs(channel, tx); - - tal_free(tmpctx); - /* We keep watching until peer finally deleted, for reorgs. */ - return KEEP_WATCHING; -} - static enum watch_result funding_lockin_cb(struct channel *channel, const struct bitcoin_tx *tx, unsigned int depth, diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index e12feba75..1aa8762e0 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -76,15 +76,6 @@ bool derive_basepoints(const struct privkey *seed UNNEEDED, /* Generated stub for extract_channel_id */ bool extract_channel_id(const u8 *in_pkt UNNEEDED, struct channel_id *channel_id UNNEEDED) { fprintf(stderr, "extract_channel_id called!\n"); abort(); } -/* Generated stub for find_htlc_out_by_ripemd */ -struct htlc_out *find_htlc_out_by_ripemd(const struct channel *channel UNNEEDED, - const struct ripemd160 *ripemd160 UNNEEDED) -{ fprintf(stderr, "find_htlc_out_by_ripemd called!\n"); abort(); } -/* Generated stub for find_txwatch */ -struct txwatch *find_txwatch(struct chain_topology *topo UNNEEDED, - const struct bitcoin_txid *txid UNNEEDED, - const struct channel *channel UNNEEDED) -{ fprintf(stderr, "find_txwatch called!\n"); abort(); } /* Generated stub for fromwire_channel_got_funding_locked */ bool fromwire_channel_got_funding_locked(const void *p UNNEEDED, size_t *plen UNNEEDED, struct pubkey *next_per_commit_point UNNEEDED) { fprintf(stderr, "fromwire_channel_got_funding_locked called!\n"); abort(); } @@ -106,27 +97,13 @@ bool fromwire_gossip_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNN /* Generated stub for fromwire_hsm_client_hsmfd_reply */ bool fromwire_hsm_client_hsmfd_reply(const void *p UNNEEDED, size_t *plen UNNEEDED) { fprintf(stderr, "fromwire_hsm_client_hsmfd_reply called!\n"); abort(); } -/* Generated stub for fromwire_onchain_add_utxo */ -bool fromwire_onchain_add_utxo(const void *p UNNEEDED, size_t *plen UNNEEDED, struct bitcoin_txid *prev_out_tx UNNEEDED, u32 *prev_out_index UNNEEDED, struct pubkey *per_commit_point UNNEEDED, u64 *value UNNEEDED) -{ fprintf(stderr, "fromwire_onchain_add_utxo called!\n"); abort(); } -/* Generated stub for fromwire_onchain_broadcast_tx */ -bool fromwire_onchain_broadcast_tx(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, size_t *plen UNNEEDED, struct bitcoin_tx **tx UNNEEDED) -{ fprintf(stderr, "fromwire_onchain_broadcast_tx called!\n"); abort(); } -/* Generated stub for fromwire_onchain_extracted_preimage */ -bool fromwire_onchain_extracted_preimage(const void *p UNNEEDED, size_t *plen UNNEEDED, struct preimage *preimage UNNEEDED) -{ fprintf(stderr, "fromwire_onchain_extracted_preimage called!\n"); abort(); } -/* Generated stub for fromwire_onchain_htlc_timeout */ -bool fromwire_onchain_htlc_timeout(const void *p UNNEEDED, size_t *plen UNNEEDED, struct htlc_stub *htlc UNNEEDED) -{ fprintf(stderr, "fromwire_onchain_htlc_timeout called!\n"); abort(); } -/* Generated stub for fromwire_onchain_init_reply */ -bool fromwire_onchain_init_reply(const void *p UNNEEDED, size_t *plen UNNEEDED, u8 *state UNNEEDED) -{ fprintf(stderr, "fromwire_onchain_init_reply called!\n"); abort(); } -/* Generated stub for fromwire_onchain_missing_htlc_output */ -bool fromwire_onchain_missing_htlc_output(const void *p UNNEEDED, size_t *plen UNNEEDED, struct htlc_stub *htlc UNNEEDED) -{ fprintf(stderr, "fromwire_onchain_missing_htlc_output called!\n"); abort(); } -/* Generated stub for fromwire_onchain_unwatch_tx */ -bool fromwire_onchain_unwatch_tx(const void *p UNNEEDED, size_t *plen UNNEEDED, struct bitcoin_txid *txid UNNEEDED) -{ fprintf(stderr, "fromwire_onchain_unwatch_tx called!\n"); abort(); } +/* Generated stub for funding_spent */ +enum watch_result funding_spent(struct channel *channel UNNEEDED, + const struct bitcoin_tx *tx UNNEEDED, + size_t input_num UNNEEDED, + const struct block *block UNNEEDED, + void *unused UNNEEDED) +{ fprintf(stderr, "funding_spent called!\n"); abort(); } /* Generated stub for get_chainparams */ struct chainparams *get_chainparams(const struct lightningd *ld UNNEEDED) { fprintf(stderr, "get_chainparams called!\n"); abort(); } @@ -304,18 +281,6 @@ struct json_result *new_json_result(const tal_t *ctx UNNEEDED) /* Generated stub for null_response */ struct json_result *null_response(const tal_t *ctx UNNEEDED) { fprintf(stderr, "null_response called!\n"); abort(); } -/* Generated stub for onchain_failed_our_htlc */ -void onchain_failed_our_htlc(const struct channel *channel UNNEEDED, - const struct htlc_stub *htlc UNNEEDED, - const char *why UNNEEDED) -{ fprintf(stderr, "onchain_failed_our_htlc called!\n"); abort(); } -/* Generated stub for onchain_fulfilled_htlc */ -void onchain_fulfilled_htlc(struct channel *channel UNNEEDED, - const struct preimage *preimage UNNEEDED) -{ fprintf(stderr, "onchain_fulfilled_htlc called!\n"); abort(); } -/* Generated stub for onchain_wire_type_name */ -const char *onchain_wire_type_name(int e UNNEEDED) -{ fprintf(stderr, "onchain_wire_type_name called!\n"); abort(); } /* Generated stub for peer_accept_channel */ u8 *peer_accept_channel(struct lightningd *ld UNNEEDED, const struct pubkey *peer_id UNNEEDED, @@ -415,21 +380,6 @@ u8 *towire_gossip_getpeers_request(const tal_t *ctx UNNEEDED, const struct pubke /* Generated stub for towire_hsm_client_hsmfd */ u8 *towire_hsm_client_hsmfd(const tal_t *ctx UNNEEDED, const struct pubkey *pubkey UNNEEDED, u64 capabilities UNNEEDED) { fprintf(stderr, "towire_hsm_client_hsmfd called!\n"); abort(); } -/* Generated stub for towire_onchain_depth */ -u8 *towire_onchain_depth(const tal_t *ctx UNNEEDED, const struct bitcoin_txid *txid UNNEEDED, u32 depth UNNEEDED) -{ fprintf(stderr, "towire_onchain_depth called!\n"); abort(); } -/* Generated stub for towire_onchain_htlc */ -u8 *towire_onchain_htlc(const tal_t *ctx UNNEEDED, const struct htlc_stub *htlc UNNEEDED, bool tell_if_missing UNNEEDED, bool tell_immediately UNNEEDED) -{ fprintf(stderr, "towire_onchain_htlc called!\n"); abort(); } -/* Generated stub for towire_onchain_init */ -u8 *towire_onchain_init(const tal_t *ctx UNNEEDED, const struct privkey *seed UNNEEDED, const struct shachain *shachain UNNEEDED, u64 funding_amount_satoshi UNNEEDED, const struct pubkey *old_remote_per_commitment_point UNNEEDED, const struct pubkey *remote_per_commitment_point UNNEEDED, u32 local_to_self_delay UNNEEDED, u32 remote_to_self_delay UNNEEDED, u32 feerate_per_kw UNNEEDED, u64 local_dust_limit_satoshi UNNEEDED, const struct pubkey *remote_revocation_basepoint UNNEEDED, const struct bitcoin_txid *our_broadcast_txid UNNEEDED, const u8 *local_scriptpubkey UNNEEDED, const u8 *remote_scriptpubkey UNNEEDED, const struct pubkey *ourwallet_pubkey UNNEEDED, enum side funder UNNEEDED, const struct pubkey *remote_payment_basepoint UNNEEDED, const struct pubkey *remote_htlc_basepoint UNNEEDED, const struct pubkey *remote_delayed_payment_basepoint UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, u32 tx_blockheight UNNEEDED, u32 reasonable_depth UNNEEDED, const secp256k1_ecdsa_signature *htlc_signature UNNEEDED, u64 num_htlcs UNNEEDED) -{ fprintf(stderr, "towire_onchain_init called!\n"); abort(); } -/* Generated stub for towire_onchain_known_preimage */ -u8 *towire_onchain_known_preimage(const tal_t *ctx UNNEEDED, const struct preimage *preimage UNNEEDED) -{ fprintf(stderr, "towire_onchain_known_preimage called!\n"); abort(); } -/* Generated stub for towire_onchain_spent */ -u8 *towire_onchain_spent(const tal_t *ctx UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, u32 input_num UNNEEDED, u32 blockheight UNNEEDED) -{ fprintf(stderr, "towire_onchain_spent called!\n"); abort(); } /* Generated stub for txfilter_add_scriptpubkey */ void txfilter_add_scriptpubkey(struct txfilter *filter UNNEEDED, u8 *script UNNEEDED) { fprintf(stderr, "txfilter_add_scriptpubkey called!\n"); abort(); } @@ -440,17 +390,6 @@ bool unsupported_features(const u8 *gfeatures UNNEEDED, const u8 *lfeatures UNNE void update_per_commit_point(struct channel *channel UNNEEDED, const struct pubkey *per_commitment_point UNNEEDED) { fprintf(stderr, "update_per_commit_point called!\n"); abort(); } -/* Generated stub for watch_tx_ */ -struct txwatch *watch_tx_(const tal_t *ctx UNNEEDED, - struct chain_topology *topo UNNEEDED, - struct channel *channel UNNEEDED, - const struct bitcoin_tx *tx UNNEEDED, - enum watch_result (*cb)(struct channel *channel UNNEEDED, - const struct bitcoin_tx * UNNEEDED, - unsigned int depth UNNEEDED, - void *) UNNEEDED, - void *cbdata UNNEEDED) -{ fprintf(stderr, "watch_tx_ called!\n"); abort(); } /* Generated stub for watch_txid_ */ struct txwatch *watch_txid_(const tal_t *ctx UNNEEDED, struct chain_topology *topo UNNEEDED,