2021-12-04 12:23:56 +01:00
|
|
|
#include "config.h"
|
2018-08-23 01:27:25 +02:00
|
|
|
#include <bitcoin/feerate.h>
|
2023-04-06 01:33:24 +02:00
|
|
|
#include <bitcoin/script.h>
|
|
|
|
#include <ccan/cast/cast.h>
|
2022-07-19 09:34:39 +02:00
|
|
|
#include <ccan/tal/str/str.h>
|
2023-04-06 01:33:24 +02:00
|
|
|
#include <common/htlc_tx.h>
|
2018-02-20 21:59:09 +01:00
|
|
|
#include <common/key_derive.h>
|
2023-04-06 01:33:24 +02:00
|
|
|
#include <common/psbt_keypath.h>
|
2021-09-16 07:00:42 +02:00
|
|
|
#include <common/type_to_string.h>
|
2022-01-03 19:45:35 +01:00
|
|
|
#include <db/exec.h>
|
2018-02-20 21:59:09 +01:00
|
|
|
#include <errno.h>
|
2021-09-16 07:00:42 +02:00
|
|
|
#include <hsmd/capabilities.h>
|
2023-04-06 01:33:24 +02:00
|
|
|
#include <hsmd/hsmd_wiregen.h>
|
2018-02-20 21:59:09 +01:00
|
|
|
#include <inttypes.h>
|
|
|
|
#include <lightningd/chaintopology.h>
|
2021-09-16 07:00:42 +02:00
|
|
|
#include <lightningd/channel.h>
|
2022-07-19 09:34:38 +02:00
|
|
|
#include <lightningd/channel_control.h>
|
2020-04-02 04:01:05 +02:00
|
|
|
#include <lightningd/coin_mvts.h>
|
2018-07-23 04:23:02 +02:00
|
|
|
#include <lightningd/hsm_control.h>
|
2018-02-20 21:59:09 +01:00
|
|
|
#include <lightningd/onchain_control.h>
|
|
|
|
#include <lightningd/peer_control.h>
|
|
|
|
#include <lightningd/subd.h>
|
2021-09-16 07:00:42 +02:00
|
|
|
#include <onchaind/onchaind_wiregen.h>
|
|
|
|
#include <wallet/txfilter.h>
|
2021-12-23 21:16:35 +01:00
|
|
|
#include <wally_bip32.h>
|
2023-04-06 01:33:24 +02:00
|
|
|
#include <wire/wire_sync.h>
|
2018-02-20 21:59:09 +01:00
|
|
|
|
|
|
|
/* 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;
|
|
|
|
|
2023-01-03 05:46:52 +01:00
|
|
|
for (hin = htlc_in_map_first(ld->htlcs_in, &ini);
|
2018-02-20 21:59:09 +01:00
|
|
|
hin;
|
2023-01-03 05:46:52 +01:00
|
|
|
hin = htlc_in_map_next(ld->htlcs_in, &ini)) {
|
2018-02-20 21:59:09 +01:00
|
|
|
if (hin->key.channel != channel)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* BOLT #5:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* A local node:
|
|
|
|
|
|
|
|
* - if it receives (or already possesses) a payment preimage
|
|
|
|
* for an unresolved HTLC output that it has been offered AND
|
|
|
|
* for which it has committed to an outgoing HTLC:
|
|
|
|
* - MUST *resolve* the output by spending it, using the
|
|
|
|
* HTLC-success transaction.
|
2021-02-22 02:58:14 +01:00
|
|
|
* - MUST NOT reveal its own preimage when it's not the final recipient...
|
2018-06-17 12:13:44 +02:00
|
|
|
* - MUST resolve the output of that HTLC-success transaction.
|
|
|
|
* - otherwise:
|
|
|
|
* - if the *remote node* is NOT irrevocably committed to
|
|
|
|
* the HTLC:
|
|
|
|
* - MUST NOT *resolve* the output by spending it.
|
2018-02-20 21:59:09 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
|
2021-12-01 17:24:31 +01:00
|
|
|
msg = towire_onchaind_known_preimage(channel, hin->preimage);
|
2018-02-20 21:59:09 +01:00
|
|
|
subd_send_msg(channel->owner, take(msg));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-13 05:45:36 +02:00
|
|
|
/* 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)
|
2018-02-20 21:59:09 +01:00
|
|
|
{
|
2021-10-13 05:45:36 +02:00
|
|
|
struct htlc_out *hout;
|
|
|
|
|
|
|
|
/* Keep valgrind happy. */
|
|
|
|
*tell_immediate = false;
|
|
|
|
|
|
|
|
/* Don't care about incoming HTLCs, just ones we offered. */
|
|
|
|
if (stub->owner == REMOTE)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
/* Might not be a current HTLC. */
|
2023-01-03 05:46:52 +01:00
|
|
|
hout = find_htlc_out(channel->peer->ld->htlcs_out, channel, stub->id);
|
2021-10-13 05:45:36 +02:00
|
|
|
if (!hout)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
/* BOLT #5:
|
|
|
|
*
|
|
|
|
* - for any committed HTLC that does NOT have an output in this
|
|
|
|
* commitment transaction:
|
|
|
|
* - once the commitment transaction has reached reasonable depth:
|
|
|
|
* - MUST fail the corresponding incoming HTLC (if any).
|
|
|
|
* - if no *valid* commitment transaction contains an output
|
|
|
|
* corresponding to the HTLC.
|
|
|
|
* - MAY fail the corresponding incoming HTLC sooner.
|
|
|
|
*/
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void handle_onchain_init_reply(struct channel *channel, const u8 *msg)
|
|
|
|
{
|
|
|
|
struct htlc_stub *stubs;
|
|
|
|
u64 commit_num;
|
|
|
|
bool *tell, *tell_immediate;
|
|
|
|
|
|
|
|
if (!fromwire_onchaind_init_reply(msg, &commit_num)) {
|
|
|
|
channel_internal_error(channel, "Invalid onchaind_init_reply %s",
|
|
|
|
tal_hex(tmpctx, msg));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-02-23 07:23:51 +01:00
|
|
|
/* FIXME: We may already be ONCHAIN state when we implement restart! */
|
feat: adds state change cause and message
This adds a `state_change` 'cause' to a channel.
A 'cause' is some initial 'reason' a channel was created or closed by:
/* Anything other than the reasons below. Should not happen. */
REASON_UNKNOWN,
/* Unconscious internal reasons, e.g. dev fail of a channel. */
REASON_LOCAL,
/* The operator or a plugin opened or closed a channel by intention. */
REASON_USER,
/* The remote closed or funded a channel with us by intention. */
REASON_REMOTE,
/* E.g. We need to close a channel because of bad signatures and such. */
REASON_PROTOCOL,
/* A channel was closed onchain, while we were offline. */
/* Note: This is very likely a conscious remote decision. */
REASON_ONCHAIN
If a 'cause' is known and a subsequent state change is made with
`REASON_UNKNOWN` the preceding cause will be used as reason, since a lot
(all `REASON_UNKNOWN`) state changes are a subsequent consequences of a prior
cause: local, user, remote, protocol or onchain.
Changelog-Added: Plugins: Channel closure resaon/cause to channel_state_changed notification
2020-10-28 11:46:12 +01:00
|
|
|
channel_set_state(channel,
|
|
|
|
FUNDING_SPEND_SEEN,
|
|
|
|
ONCHAIN,
|
|
|
|
REASON_UNKNOWN,
|
|
|
|
"Onchain init reply");
|
2021-10-13 05:45:36 +02:00
|
|
|
|
|
|
|
/* Tell it about any relevant HTLCs */
|
|
|
|
/* FIXME: Filter by commitnum! */
|
2021-10-13 05:45:36 +02:00
|
|
|
stubs = wallet_htlc_stubs(tmpctx, channel->peer->ld->wallet, channel,
|
|
|
|
commit_num);
|
2021-10-13 05:45:36 +02:00
|
|
|
tell = tal_arr(stubs, bool, tal_count(stubs));
|
|
|
|
tell_immediate = tal_arr(stubs, bool, tal_count(stubs));
|
|
|
|
|
|
|
|
for (size_t i = 0; i < tal_count(stubs); i++) {
|
|
|
|
tell[i] = tell_if_missing(channel, &stubs[i],
|
|
|
|
&tell_immediate[i]);
|
|
|
|
}
|
|
|
|
msg = towire_onchaind_htlcs(channel, stubs, tell, tell_immediate);
|
|
|
|
subd_send_msg(channel->owner, take(msg));
|
|
|
|
|
|
|
|
/* Tell it about any preimages we know. */
|
|
|
|
onchaind_tell_fulfill(channel);
|
2018-02-20 21:59:09 +01:00
|
|
|
}
|
|
|
|
|
2018-04-16 13:20:45 +02:00
|
|
|
/**
|
|
|
|
* Notify onchaind about the depth change of the watched tx.
|
|
|
|
*/
|
|
|
|
static void onchain_tx_depth(struct channel *channel,
|
|
|
|
const struct bitcoin_txid *txid,
|
2021-12-01 17:24:31 +01:00
|
|
|
unsigned int depth)
|
2018-04-16 13:20:45 +02:00
|
|
|
{
|
|
|
|
u8 *msg;
|
2021-12-01 17:24:31 +01:00
|
|
|
msg = towire_onchaind_depth(channel, txid, depth);
|
2018-04-16 13:20:45 +02:00
|
|
|
subd_send_msg(channel->owner, take(msg));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Entrypoint for the txwatch callback, calls onchain_tx_depth.
|
|
|
|
*/
|
2018-08-13 05:05:33 +02:00
|
|
|
static enum watch_result onchain_tx_watched(struct lightningd *ld,
|
|
|
|
struct channel *channel,
|
2018-04-09 15:20:54 +02:00
|
|
|
const struct bitcoin_txid *txid,
|
2019-06-28 03:58:31 +02:00
|
|
|
const struct bitcoin_tx *tx,
|
2018-02-20 21:59:09 +01:00
|
|
|
unsigned int depth)
|
2018-02-20 21:59:09 +01:00
|
|
|
{
|
2018-08-13 05:05:33 +02:00
|
|
|
u32 blockheight = get_block_height(ld->topology);
|
2019-06-28 03:58:31 +02:00
|
|
|
|
|
|
|
if (tx != NULL) {
|
|
|
|
struct bitcoin_txid txid2;
|
|
|
|
|
|
|
|
bitcoin_txid(tx, &txid2);
|
|
|
|
if (!bitcoin_txid_eq(txid, &txid2)) {
|
|
|
|
channel_internal_error(channel, "Txid for %s is not %s",
|
|
|
|
type_to_string(tmpctx,
|
|
|
|
struct bitcoin_tx,
|
|
|
|
tx),
|
|
|
|
type_to_string(tmpctx,
|
|
|
|
struct bitcoin_txid,
|
|
|
|
txid));
|
|
|
|
return DELETE_WATCH;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-20 21:59:09 +01:00
|
|
|
if (depth == 0) {
|
|
|
|
log_unusual(channel->log, "Chain reorganization!");
|
2019-07-25 04:47:34 +02:00
|
|
|
channel_set_owner(channel, NULL);
|
2018-02-20 21:59:09 +01:00
|
|
|
|
|
|
|
/* We will most likely be freed, so this is a noop */
|
|
|
|
return KEEP_WATCHING;
|
|
|
|
}
|
|
|
|
|
2018-04-17 15:20:27 +02:00
|
|
|
/* Store the channeltx so we can replay later */
|
2018-08-13 05:05:33 +02:00
|
|
|
wallet_channeltxs_add(ld->wallet, channel,
|
2020-08-25 04:15:48 +02:00
|
|
|
WIRE_ONCHAIND_DEPTH, txid, 0, blockheight);
|
2018-04-17 15:20:27 +02:00
|
|
|
|
2021-12-01 17:24:31 +01:00
|
|
|
onchain_tx_depth(channel, txid, depth);
|
2018-02-20 21:59:09 +01:00
|
|
|
return KEEP_WATCHING;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void watch_tx_and_outputs(struct channel *channel,
|
|
|
|
const struct bitcoin_tx *tx);
|
|
|
|
|
2018-04-16 13:20:45 +02:00
|
|
|
/**
|
|
|
|
* Notify onchaind that an output was spent and register new watches.
|
|
|
|
*/
|
2021-12-01 17:24:31 +01:00
|
|
|
static void onchain_txo_spent(struct channel *channel, const struct bitcoin_tx *tx, size_t input_num, u32 blockheight)
|
2018-02-20 21:59:09 +01:00
|
|
|
{
|
|
|
|
u8 *msg;
|
2020-05-26 05:39:40 +02:00
|
|
|
/* Onchaind needs all inputs, since it uses those to compare
|
|
|
|
* with existing spends (which can vary, with feerate changes). */
|
|
|
|
struct tx_parts *parts = tx_parts_from_wally_tx(tmpctx, tx->wtx,
|
|
|
|
-1, -1);
|
2018-02-20 21:59:09 +01:00
|
|
|
|
|
|
|
watch_tx_and_outputs(channel, tx);
|
|
|
|
|
2021-12-01 17:24:31 +01:00
|
|
|
msg = towire_onchaind_spent(channel, parts, input_num, blockheight);
|
2018-02-20 21:59:09 +01:00
|
|
|
subd_send_msg(channel->owner, take(msg));
|
|
|
|
|
2018-04-16 13:20:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Entrypoint for the txowatch callback, stores tx and calls onchain_txo_spent.
|
|
|
|
*/
|
|
|
|
static enum watch_result onchain_txo_watched(struct channel *channel,
|
|
|
|
const struct bitcoin_tx *tx,
|
|
|
|
size_t input_num,
|
|
|
|
const struct block *block)
|
|
|
|
{
|
2018-04-17 15:20:27 +02:00
|
|
|
struct bitcoin_txid txid;
|
|
|
|
bitcoin_txid(tx, &txid);
|
|
|
|
|
|
|
|
/* Store the channeltx so we can replay later */
|
|
|
|
wallet_channeltxs_add(channel->peer->ld->wallet, channel,
|
2020-08-25 04:15:48 +02:00
|
|
|
WIRE_ONCHAIND_SPENT, &txid, input_num,
|
2018-04-17 15:20:27 +02:00
|
|
|
block->height);
|
|
|
|
|
2021-12-01 17:24:31 +01:00
|
|
|
onchain_txo_spent(channel, tx, input_num, block->height);
|
2018-04-16 13:20:45 +02:00
|
|
|
|
2018-02-20 21:59:09 +01:00
|
|
|
/* 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)
|
|
|
|
{
|
2021-10-13 05:45:36 +02:00
|
|
|
struct bitcoin_outpoint outpoint;
|
2018-02-20 21:59:09 +01:00
|
|
|
struct txwatch *txw;
|
|
|
|
struct lightningd *ld = channel->peer->ld;
|
|
|
|
|
2021-10-13 05:45:36 +02:00
|
|
|
bitcoin_txid(tx, &outpoint.txid);
|
2018-02-20 21:59:09 +01:00
|
|
|
|
|
|
|
/* Make txwatch a parent of txo watches, so we can unwatch together. */
|
|
|
|
txw = watch_tx(channel->owner, ld->topology, channel, tx,
|
2018-02-20 21:59:09 +01:00
|
|
|
onchain_tx_watched);
|
2018-02-20 21:59:09 +01:00
|
|
|
|
2021-10-13 05:45:36 +02:00
|
|
|
for (outpoint.n = 0; outpoint.n < tx->wtx->num_outputs; outpoint.n++)
|
|
|
|
watch_txo(txw, ld->topology, channel, &outpoint,
|
2018-02-20 21:59:09 +01:00
|
|
|
onchain_txo_watched);
|
2018-02-20 21:59:09 +01:00
|
|
|
}
|
|
|
|
|
2020-04-02 04:16:32 +02:00
|
|
|
static void handle_onchain_log_coin_move(struct channel *channel, const u8 *msg)
|
|
|
|
{
|
|
|
|
struct chain_coin_mvt *mvt = tal(NULL, struct chain_coin_mvt);
|
|
|
|
|
2020-08-25 04:15:48 +02:00
|
|
|
if (!fromwire_onchaind_notify_coin_mvt(msg, mvt)) {
|
2020-04-02 04:16:32 +02:00
|
|
|
channel_internal_error(channel, "Invalid onchain notify_coin_mvt");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-12-01 16:37:23 +01:00
|
|
|
/* Any 'ignored' payments get registed to the wallet */
|
|
|
|
if (!mvt->account_name)
|
|
|
|
mvt->account_name = type_to_string(mvt, struct channel_id,
|
|
|
|
&channel->cid);
|
2022-02-08 21:40:55 +01:00
|
|
|
else
|
2022-01-24 19:58:39 +01:00
|
|
|
mvt->originating_acct = type_to_string(mvt, struct channel_id,
|
|
|
|
&channel->cid);
|
2020-04-02 04:16:32 +02:00
|
|
|
notify_chain_mvt(channel->peer->ld, mvt);
|
|
|
|
tal_free(mvt);
|
|
|
|
}
|
|
|
|
|
2018-02-20 21:59:09 +01:00
|
|
|
static void handle_onchain_unwatch_tx(struct channel *channel, const u8 *msg)
|
|
|
|
{
|
|
|
|
struct bitcoin_txid txid;
|
|
|
|
struct txwatch *txw;
|
|
|
|
|
2020-08-25 04:15:48 +02:00
|
|
|
if (!fromwire_onchaind_unwatch_tx(msg, &txid)) {
|
2018-02-20 21:59:09 +01:00
|
|
|
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",
|
2018-03-15 05:30:39 +01:00
|
|
|
type_to_string(tmpctx, struct bitcoin_txid, &txid));
|
2018-02-20 21:59:09 +01:00
|
|
|
tal_free(txw);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void handle_extracted_preimage(struct channel *channel, const u8 *msg)
|
|
|
|
{
|
|
|
|
struct preimage preimage;
|
|
|
|
|
2020-08-25 04:15:48 +02:00
|
|
|
if (!fromwire_onchaind_extracted_preimage(msg, &preimage)) {
|
2018-02-20 21:59:09 +01:00
|
|
|
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;
|
|
|
|
|
2020-08-25 04:15:48 +02:00
|
|
|
if (!fromwire_onchaind_missing_htlc_output(msg, &htlc)) {
|
2018-02-20 21:59:09 +01:00
|
|
|
channel_internal_error(channel, "Invalid missing_htlc_output");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-03-30 05:43:12 +02:00
|
|
|
/* We only set tell_if_missing on LOCAL htlcs */
|
|
|
|
if (htlc.owner != LOCAL) {
|
|
|
|
channel_internal_error(channel,
|
|
|
|
"onchaind_missing_htlc_output: htlc %"PRIu64" is not local!",
|
|
|
|
htlc.id);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-02-20 21:59:09 +01:00
|
|
|
/* BOLT #5:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* - for any committed HTLC that does NOT have an output in this
|
|
|
|
* commitment transaction:
|
|
|
|
* - once the commitment transaction has reached reasonable depth:
|
|
|
|
* - MUST fail the corresponding incoming HTLC (if any).
|
|
|
|
* - if no *valid* commitment transaction contains an output
|
|
|
|
* corresponding to the HTLC.
|
|
|
|
* - MAY fail the corresponding incoming HTLC sooner.
|
2018-02-20 21:59:09 +01:00
|
|
|
*/
|
2022-03-30 05:43:12 +02:00
|
|
|
onchain_failed_our_htlc(channel, &htlc, "missing in commitment tx", false);
|
2018-02-20 21:59:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void handle_onchain_htlc_timeout(struct channel *channel, const u8 *msg)
|
|
|
|
{
|
|
|
|
struct htlc_stub htlc;
|
|
|
|
|
2020-08-25 04:15:48 +02:00
|
|
|
if (!fromwire_onchaind_htlc_timeout(msg, &htlc)) {
|
2018-02-20 21:59:09 +01:00
|
|
|
channel_internal_error(channel, "Invalid onchain_htlc_timeout");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-03-30 05:43:12 +02:00
|
|
|
/* It should tell us about timeouts on our LOCAL htlcs */
|
|
|
|
if (htlc.owner != LOCAL) {
|
|
|
|
channel_internal_error(channel,
|
|
|
|
"onchaind_htlc_timeout: htlc %"PRIu64" is not local!",
|
|
|
|
htlc.id);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-02-20 21:59:09 +01:00
|
|
|
/* BOLT #5:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* - if the commitment transaction HTLC output has *timed out* and
|
|
|
|
* hasn't been *resolved*:
|
|
|
|
* - MUST *resolve* the output by spending it using the HTLC-timeout
|
|
|
|
* transaction.
|
2018-02-20 21:59:09 +01:00
|
|
|
*/
|
2022-03-30 05:43:12 +02:00
|
|
|
onchain_failed_our_htlc(channel, &htlc, "timed out", true);
|
2018-02-20 21:59:09 +01:00
|
|
|
}
|
|
|
|
|
2018-04-02 15:48:39 +02:00
|
|
|
static void handle_irrevocably_resolved(struct channel *channel, const u8 *msg UNUSED)
|
2018-02-20 21:59:09 +01:00
|
|
|
{
|
|
|
|
/* 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. */
|
2018-02-21 16:50:49 +01:00
|
|
|
delete_channel(channel);
|
2018-02-20 21:59:09 +01:00
|
|
|
}
|
|
|
|
|
2021-12-06 19:24:20 +01:00
|
|
|
|
2018-02-20 21:59:09 +01:00
|
|
|
/**
|
|
|
|
* onchain_add_utxo -- onchaind is telling us about an UTXO we own
|
|
|
|
*/
|
|
|
|
static void onchain_add_utxo(struct channel *channel, const u8 *msg)
|
|
|
|
{
|
2020-04-02 04:01:05 +02:00
|
|
|
struct chain_coin_mvt *mvt;
|
2018-03-22 00:18:53 +01:00
|
|
|
u32 blockheight;
|
2021-10-13 05:45:36 +02:00
|
|
|
struct bitcoin_outpoint outpoint;
|
|
|
|
u32 csv_lock;
|
2020-07-06 07:28:43 +02:00
|
|
|
struct amount_sat amount;
|
|
|
|
struct pubkey *commitment_point;
|
|
|
|
u8 *scriptPubkey;
|
2018-02-20 21:59:09 +01:00
|
|
|
|
2020-08-25 04:15:48 +02:00
|
|
|
if (!fromwire_onchaind_add_utxo(
|
2021-10-13 05:45:36 +02:00
|
|
|
tmpctx, msg, &outpoint, &commitment_point,
|
2021-07-02 21:54:40 +02:00
|
|
|
&amount, &blockheight, &scriptPubkey,
|
|
|
|
&csv_lock)) {
|
2020-07-06 07:28:43 +02:00
|
|
|
log_broken(channel->log,
|
|
|
|
"onchaind gave invalid add_utxo message: %s",
|
|
|
|
tal_hex(msg, msg));
|
|
|
|
return;
|
2018-02-20 21:59:09 +01:00
|
|
|
}
|
|
|
|
|
2020-07-06 07:28:43 +02:00
|
|
|
assert(blockheight);
|
|
|
|
outpointfilter_add(channel->peer->ld->wallet->owned_outpoints,
|
2021-10-13 05:45:36 +02:00
|
|
|
&outpoint);
|
|
|
|
log_debug(channel->log, "adding utxo to watch %s, csv %u",
|
|
|
|
type_to_string(tmpctx, struct bitcoin_outpoint, &outpoint),
|
|
|
|
csv_lock);
|
2021-07-02 21:54:40 +02:00
|
|
|
|
2020-07-06 07:28:43 +02:00
|
|
|
wallet_add_onchaind_utxo(channel->peer->ld->wallet,
|
2021-10-13 05:45:36 +02:00
|
|
|
&outpoint, scriptPubkey,
|
2020-07-06 07:28:43 +02:00
|
|
|
blockheight, amount, channel,
|
2021-07-02 21:54:40 +02:00
|
|
|
commitment_point,
|
|
|
|
csv_lock);
|
2020-04-02 04:01:05 +02:00
|
|
|
|
2021-12-01 16:32:55 +01:00
|
|
|
mvt = new_coin_wallet_deposit(msg, &outpoint, blockheight,
|
2022-02-16 19:17:53 +01:00
|
|
|
amount, DEPOSIT);
|
|
|
|
mvt->originating_acct = type_to_string(mvt, struct channel_id,
|
|
|
|
&channel->cid);
|
2021-12-06 19:24:20 +01:00
|
|
|
|
2020-04-02 04:01:05 +02:00
|
|
|
notify_chain_mvt(channel->peer->ld, mvt);
|
2018-02-20 21:59:09 +01:00
|
|
|
}
|
|
|
|
|
2019-10-04 12:27:48 +02:00
|
|
|
static void onchain_annotate_txout(struct channel *channel, const u8 *msg)
|
2019-05-27 13:06:02 +02:00
|
|
|
{
|
2021-10-13 05:45:36 +02:00
|
|
|
struct bitcoin_outpoint outpoint;
|
2019-06-07 11:38:20 +02:00
|
|
|
enum wallet_tx_type type;
|
2021-10-13 05:45:36 +02:00
|
|
|
if (!fromwire_onchaind_annotate_txout(msg, &outpoint, &type))
|
2019-10-04 12:27:48 +02:00
|
|
|
fatal("onchaind gave invalid onchain_annotate_txout "
|
2019-05-27 13:06:02 +02:00
|
|
|
"message: %s",
|
|
|
|
tal_hex(msg, msg));
|
2021-10-13 05:45:36 +02:00
|
|
|
wallet_annotate_txout(channel->peer->ld->wallet, &outpoint, type,
|
2019-10-04 12:27:48 +02:00
|
|
|
channel->dbid);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void onchain_annotate_txin(struct channel *channel, const u8 *msg)
|
|
|
|
{
|
|
|
|
struct bitcoin_txid txid;
|
|
|
|
enum wallet_tx_type type;
|
|
|
|
u32 innum;
|
2020-08-25 04:15:48 +02:00
|
|
|
if (!fromwire_onchaind_annotate_txin(msg, &txid, &innum, &type))
|
2019-10-04 12:27:48 +02:00
|
|
|
fatal("onchaind gave invalid onchain_annotate_txin "
|
|
|
|
"message: %s",
|
|
|
|
tal_hex(msg, msg));
|
|
|
|
wallet_annotate_txin(channel->peer->ld->wallet, &txid, innum, type,
|
2019-05-27 13:06:02 +02:00
|
|
|
channel->dbid);
|
|
|
|
}
|
|
|
|
|
2023-04-06 01:33:24 +02:00
|
|
|
/* All onchaind-produced txs are actually of the same form: */
|
|
|
|
struct onchain_signing_info {
|
|
|
|
/* Fields common to every callback: */
|
|
|
|
struct channel *channel;
|
|
|
|
|
|
|
|
/* Minimum block */
|
|
|
|
u32 minblock;
|
|
|
|
|
|
|
|
/* Block we want this mined by */
|
|
|
|
u32 deadline_block;
|
|
|
|
|
|
|
|
/* Witness script for tx */
|
|
|
|
u8 *wscript;
|
|
|
|
/* Trailing element for witness stack */
|
|
|
|
const tal_t *stack_elem;
|
|
|
|
|
|
|
|
/* Tagged union (for sanity checking!) */
|
|
|
|
enum onchaind_wire msgtype;
|
|
|
|
union {
|
|
|
|
/* WIRE_ONCHAIND_SPEND_HTLC_TIMEDOUT */
|
|
|
|
struct {
|
|
|
|
u64 commit_num;
|
|
|
|
} htlc_timedout;
|
2023-04-06 01:33:24 +02:00
|
|
|
/* WIRE_ONCHAIND_SPEND_PENALTY */
|
|
|
|
struct {
|
|
|
|
struct secret remote_per_commitment_secret;
|
|
|
|
} spend_penalty;
|
2023-04-06 01:33:24 +02:00
|
|
|
/* WIRE_ONCHAIND_SPEND_HTLC_SUCCESS */
|
|
|
|
struct {
|
|
|
|
u64 commit_num;
|
|
|
|
struct bitcoin_signature remote_htlc_sig;
|
|
|
|
struct preimage preimage;
|
|
|
|
} htlc_success;
|
2023-04-06 01:33:25 +02:00
|
|
|
/* WIRE_ONCHAIND_SPEND_HTLC_TIMEOUT */
|
|
|
|
struct {
|
|
|
|
u64 commit_num;
|
|
|
|
struct bitcoin_signature remote_htlc_sig;
|
|
|
|
} htlc_timeout;
|
2023-04-06 01:33:25 +02:00
|
|
|
/* WIRE_ONCHAIND_SPEND_FULFILL */
|
|
|
|
struct {
|
|
|
|
struct pubkey remote_per_commitment_point;
|
|
|
|
struct preimage preimage;
|
|
|
|
} fulfill;
|
2023-04-06 01:33:25 +02:00
|
|
|
/* WIRE_ONCHAIND_SPEND_HTLC_EXPIRED */
|
|
|
|
struct {
|
|
|
|
struct pubkey remote_per_commitment_point;
|
|
|
|
} htlc_expired;
|
2023-04-06 01:33:24 +02:00
|
|
|
} u;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* If we don't care / don't know */
|
|
|
|
static u32 infinite_block_deadline(const struct chain_topology *topo)
|
|
|
|
{
|
|
|
|
return get_block_height(topo) + 300;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct onchain_signing_info *new_signing_info(const tal_t *ctx,
|
|
|
|
struct channel *channel,
|
|
|
|
enum onchaind_wire msgtype)
|
|
|
|
{
|
|
|
|
struct onchain_signing_info *info = tal(ctx, struct onchain_signing_info);
|
|
|
|
info->channel = channel;
|
|
|
|
info->msgtype = msgtype;
|
|
|
|
return info;
|
|
|
|
}
|
|
|
|
|
|
|
|
static u8 *sign_tx_to_us(const tal_t *ctx,
|
|
|
|
const struct bitcoin_tx *tx,
|
|
|
|
const struct onchain_signing_info *info)
|
|
|
|
{
|
|
|
|
assert(info->msgtype == WIRE_ONCHAIND_SPEND_TO_US);
|
|
|
|
return towire_hsmd_sign_any_delayed_payment_to_us(ctx,
|
|
|
|
info->u.htlc_timedout.commit_num,
|
|
|
|
tx, info->wscript,
|
|
|
|
0,
|
|
|
|
&info->channel->peer->id,
|
|
|
|
info->channel->dbid);
|
|
|
|
}
|
|
|
|
|
2023-04-06 01:33:24 +02:00
|
|
|
static u8 *sign_penalty(const tal_t *ctx,
|
|
|
|
const struct bitcoin_tx *tx,
|
|
|
|
const struct onchain_signing_info *info)
|
|
|
|
{
|
|
|
|
assert(info->msgtype == WIRE_ONCHAIND_SPEND_PENALTY);
|
|
|
|
return towire_hsmd_sign_any_penalty_to_us(ctx,
|
|
|
|
&info->u.spend_penalty.remote_per_commitment_secret,
|
|
|
|
tx, info->wscript,
|
|
|
|
0,
|
|
|
|
&info->channel->peer->id,
|
|
|
|
info->channel->dbid);
|
|
|
|
}
|
|
|
|
|
2023-04-06 01:33:24 +02:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2023-04-06 01:33:25 +02:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2023-04-06 01:33:25 +02:00
|
|
|
static u8 *sign_fulfill(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_FULFILL);
|
|
|
|
return towire_hsmd_sign_any_remote_htlc_to_us(ctx,
|
|
|
|
&info->u.fulfill.remote_per_commitment_point,
|
|
|
|
tx, info->wscript,
|
|
|
|
anchor_outputs,
|
|
|
|
0,
|
|
|
|
&info->channel->peer->id,
|
|
|
|
info->channel->dbid);
|
|
|
|
}
|
|
|
|
|
2023-04-06 01:33:25 +02:00
|
|
|
static u8 *sign_htlc_expired(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_EXPIRED);
|
|
|
|
return towire_hsmd_sign_any_remote_htlc_to_us(ctx,
|
|
|
|
&info->u.htlc_expired.remote_per_commitment_point,
|
|
|
|
tx, info->wscript,
|
|
|
|
anchor_outputs,
|
|
|
|
0,
|
|
|
|
&info->channel->peer->id,
|
|
|
|
info->channel->dbid);
|
|
|
|
}
|
|
|
|
|
2023-04-06 01:33:24 +02:00
|
|
|
/* Matches bitcoin_witness_sig_and_element! */
|
|
|
|
static const struct onchain_witness_element **
|
|
|
|
onchain_witness_sig_and_element(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_sig_and_element */
|
|
|
|
welements[i]->is_signature = (i == 0);
|
|
|
|
welements[i]->witness = tal_dup_talarr(welements[i], u8,
|
|
|
|
witness[i]);
|
|
|
|
}
|
|
|
|
return cast_const2(const struct onchain_witness_element **, welements);
|
|
|
|
}
|
|
|
|
|
2023-04-06 01:33:24 +02:00
|
|
|
/* 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);
|
|
|
|
}
|
|
|
|
|
2023-04-07 06:58:17 +02:00
|
|
|
/* feerate_for_deadline, but really lowball for distant targets */
|
|
|
|
static u32 feerate_for_target(const struct chain_topology *topo, u64 deadline)
|
|
|
|
{
|
|
|
|
u64 blocks, blockheight;
|
|
|
|
|
|
|
|
blockheight = get_block_height(topo);
|
|
|
|
|
|
|
|
/* Past deadline? Want it now. */
|
|
|
|
if (blockheight > deadline)
|
|
|
|
return feerate_for_deadline(topo, 1);
|
|
|
|
|
|
|
|
blocks = deadline - blockheight;
|
|
|
|
|
|
|
|
/* Over 200 blocks, we *always* use min fee! */
|
|
|
|
if (blocks > 200)
|
|
|
|
return FEERATE_FLOOR;
|
|
|
|
/* Over 100 blocks, use min fee bitcoind will accept */
|
|
|
|
if (blocks > 100)
|
|
|
|
return get_feerate_floor(topo);
|
|
|
|
|
|
|
|
return feerate_for_deadline(topo, blocks);
|
|
|
|
}
|
|
|
|
|
2023-04-06 01:33:24 +02:00
|
|
|
/* 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().
|
|
|
|
*/
|
|
|
|
static struct bitcoin_tx *onchaind_tx(const tal_t *ctx,
|
|
|
|
struct channel *channel,
|
|
|
|
const struct bitcoin_outpoint *out,
|
|
|
|
struct amount_sat out_sats,
|
|
|
|
u32 to_self_delay,
|
|
|
|
u32 locktime,
|
|
|
|
u8 *(*sign)(const tal_t *ctx,
|
|
|
|
const struct bitcoin_tx *tx,
|
|
|
|
const struct onchain_signing_info *info),
|
|
|
|
const struct onchain_signing_info *info,
|
|
|
|
bool *worthwhile,
|
|
|
|
const struct onchain_witness_element ***welements)
|
|
|
|
{
|
|
|
|
struct bitcoin_tx *tx;
|
2023-04-07 06:58:17 +02:00
|
|
|
struct amount_sat amt;
|
2023-04-06 01:33:24 +02:00
|
|
|
struct bitcoin_signature sig;
|
|
|
|
size_t weight;
|
|
|
|
u8 *msg;
|
|
|
|
u8 **witness;
|
|
|
|
struct pubkey final_key;
|
|
|
|
struct ext_key final_wallet_ext_key;
|
2023-04-07 06:58:17 +02:00
|
|
|
u64 block_target;
|
2023-04-06 01:33:24 +02:00
|
|
|
struct lightningd *ld = channel->peer->ld;
|
|
|
|
|
|
|
|
bip32_pubkey(ld, &final_key, channel->final_key_idx);
|
|
|
|
if (bip32_key_from_parent(ld->bip32_base,
|
|
|
|
channel->final_key_idx,
|
|
|
|
BIP32_FLAG_KEY_PUBLIC,
|
|
|
|
&final_wallet_ext_key) != WALLY_OK) {
|
|
|
|
channel_internal_error(channel,
|
|
|
|
"Could not derive final_wallet_ext_key %"PRIu64,
|
|
|
|
channel->final_key_idx);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
tx = bitcoin_tx(ctx, chainparams, 1, 1, locktime);
|
|
|
|
bitcoin_tx_add_input(tx, out, to_self_delay,
|
|
|
|
NULL, out_sats, NULL, info->wscript);
|
|
|
|
|
|
|
|
bitcoin_tx_add_output(
|
|
|
|
tx, scriptpubkey_p2wpkh(tmpctx, &final_key), NULL, out_sats);
|
|
|
|
psbt_add_keypath_to_last_output(tx, channel->final_key_idx, &final_wallet_ext_key);
|
|
|
|
|
|
|
|
/* Worst-case sig is 73 bytes */
|
|
|
|
weight = bitcoin_tx_weight(tx) + 1 + 3 + 73 + 0 + tal_count(info->wscript);
|
|
|
|
weight += elements_tx_overhead(chainparams, 1, 1);
|
2023-04-07 06:58:17 +02:00
|
|
|
|
|
|
|
block_target = info->deadline_block;
|
|
|
|
for (;;) {
|
|
|
|
struct amount_sat fee;
|
|
|
|
u32 feerate;
|
|
|
|
|
|
|
|
feerate = feerate_for_target(ld->topology, block_target);
|
|
|
|
fee = amount_tx_fee(feerate, weight);
|
|
|
|
|
|
|
|
log_debug(channel->log,
|
|
|
|
"Feerate for target %"PRIu64" (%+"PRId64" blocks) is %u, fee %s of %s",
|
|
|
|
block_target,
|
|
|
|
block_target - get_block_height(ld->topology),
|
|
|
|
feerate,
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &fee),
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &out_sats));
|
|
|
|
|
|
|
|
/* If we can afford fee and it's not dust, we're done */
|
|
|
|
if (amount_sat_sub(&amt, out_sats, fee)
|
|
|
|
&& amount_sat_greater_eq(amt, channel->our_config.dust_limit))
|
|
|
|
break;
|
|
|
|
|
|
|
|
/* Hmm, can't afford with recommended fee. Try increasing deadline! */
|
|
|
|
block_target++;
|
|
|
|
|
|
|
|
/* If we can't even afford at FEERATE_FLOOR, something is wrong! */
|
|
|
|
if (feerate == FEERATE_FLOOR) {
|
|
|
|
amt = channel->our_config.dust_limit;
|
|
|
|
log_broken(channel->log, "TX can't afford minimal feerate"
|
|
|
|
"; setting output to %s",
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &amt));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If we anticipate waiting a long time (say, 20 blocks past
|
|
|
|
* the deadline), tell onchaind not to wait */
|
|
|
|
*worthwhile = (block_target < info->deadline_block + (u64)20);
|
|
|
|
|
|
|
|
/* If we came close to target, it's worthwhile to wait for. */
|
|
|
|
if (block_target != info->deadline_block)
|
|
|
|
log_debug(channel->log, "Had to adjust deadline from %u to %"PRIu64" for %s",
|
|
|
|
info->deadline_block, block_target,
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &out_sats));
|
|
|
|
|
|
|
|
if (!*worthwhile) {
|
|
|
|
log_unusual(channel->log,
|
|
|
|
"Lowballing feerate for %s sats from %u to %u (deadline %u->%"PRIu64"):"
|
|
|
|
" won't count on it being spent!",
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &out_sats),
|
|
|
|
feerate_for_target(ld->topology, info->deadline_block),
|
|
|
|
feerate_for_target(ld->topology, block_target),
|
|
|
|
info->deadline_block, block_target);
|
2023-04-06 01:33:24 +02:00
|
|
|
}
|
2023-04-07 06:58:17 +02:00
|
|
|
|
2023-04-06 01:33:24 +02:00
|
|
|
bitcoin_tx_output_set_amount(tx, 0, amt);
|
|
|
|
bitcoin_tx_finalize(tx);
|
|
|
|
|
|
|
|
/* Now sign, and set witness */
|
|
|
|
msg = sign(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_sig_and_element(NULL, &sig, info->stack_elem,
|
|
|
|
tal_bytelen(info->stack_elem),
|
|
|
|
info->wscript);
|
|
|
|
*welements = onchain_witness_sig_and_element(ctx, witness);
|
|
|
|
bitcoin_tx_input_set_witness(tx, 0, take(witness));
|
|
|
|
|
|
|
|
return tx;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool consider_onchain_rebroadcast(struct channel *channel,
|
|
|
|
const struct bitcoin_tx **tx,
|
|
|
|
struct onchain_signing_info *info)
|
|
|
|
{
|
|
|
|
/* FIXME: Implement rbf! */
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2023-04-06 01:33:24 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2023-04-06 01:33:25 +02:00
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
2023-04-06 01:33:24 +02:00
|
|
|
/* Create the onchain tx and tell onchaind about it */
|
|
|
|
static void create_onchain_tx(struct channel *channel,
|
|
|
|
const struct bitcoin_outpoint *out,
|
|
|
|
struct amount_sat out_sats,
|
|
|
|
u32 to_self_delay,
|
|
|
|
u32 locktime,
|
|
|
|
u8 *(*sign)(const tal_t *ctx,
|
|
|
|
const struct bitcoin_tx *tx,
|
|
|
|
const struct onchain_signing_info *info),
|
|
|
|
struct onchain_signing_info *info STEALS,
|
|
|
|
const char *caller)
|
|
|
|
{
|
|
|
|
struct bitcoin_tx *tx;
|
|
|
|
const struct onchain_witness_element **welements;
|
|
|
|
bool worthwhile;
|
2023-04-07 06:58:17 +02:00
|
|
|
struct lightningd *ld = channel->peer->ld;
|
2023-04-06 01:33:24 +02:00
|
|
|
|
|
|
|
tx = onchaind_tx(tmpctx, channel,
|
2023-04-07 06:58:17 +02:00
|
|
|
out, out_sats, to_self_delay, locktime,
|
2023-04-06 01:33:24 +02:00
|
|
|
sign, info, &worthwhile, &welements);
|
|
|
|
if (!tx)
|
|
|
|
return;
|
|
|
|
|
|
|
|
log_debug(channel->log, "Broadcast for onchaind tx %s%s",
|
|
|
|
type_to_string(tmpctx, struct bitcoin_tx, tx),
|
|
|
|
worthwhile ? "" : "(NOT WORTHWHILE, LOWBALL FEE!)");
|
|
|
|
|
2023-04-07 06:58:17 +02:00
|
|
|
broadcast_tx(ld->topology,
|
2023-04-06 01:33:24 +02:00
|
|
|
channel, take(tx), NULL, false, info->minblock,
|
|
|
|
NULL, consider_onchain_rebroadcast, take(info));
|
|
|
|
|
|
|
|
subd_send_msg(channel->owner,
|
|
|
|
take(towire_onchaind_spend_created(NULL,
|
|
|
|
worthwhile,
|
|
|
|
welements)));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void handle_onchaind_spend_to_us(struct channel *channel,
|
|
|
|
const u8 *msg)
|
|
|
|
{
|
|
|
|
struct onchain_signing_info *info;
|
|
|
|
struct bitcoin_outpoint out;
|
|
|
|
struct amount_sat out_sats;
|
|
|
|
|
|
|
|
info = new_signing_info(msg, channel, WIRE_ONCHAIND_SPEND_TO_US);
|
|
|
|
|
|
|
|
/* BOLT #3:
|
|
|
|
* #### `to_local` Output
|
|
|
|
*...
|
|
|
|
* The output is spent by an input with `nSequence` field set to `to_self_delay` (which can only be valid after that duration has passed) and witness:
|
|
|
|
*
|
|
|
|
* <local_delayedsig> <>
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* BOLT #3:
|
|
|
|
* ## HTLC-Timeout and HTLC-Success Transactions
|
|
|
|
*
|
|
|
|
* These HTLC transactions are almost identical, except the HTLC-timeout transaction is timelocked.
|
|
|
|
*...
|
|
|
|
* To spend this via penalty, the remote node uses a witness stack
|
|
|
|
* `<revocationsig> 1`, and to collect the output, the local node uses
|
|
|
|
* an input with nSequence `to_self_delay` and a witness stack
|
|
|
|
* `<local_delayedsig> 0`.
|
|
|
|
*/
|
|
|
|
info->stack_elem = NULL;
|
|
|
|
|
|
|
|
if (!fromwire_onchaind_spend_to_us(info, msg,
|
|
|
|
&out, &out_sats,
|
|
|
|
&info->minblock,
|
|
|
|
&info->u.htlc_timedout.commit_num,
|
|
|
|
&info->wscript)) {
|
|
|
|
channel_internal_error(channel, "Invalid onchaind_spend_to_us %s",
|
|
|
|
tal_hex(tmpctx, msg));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* No real deadline on this, it's just returning to our wallet. */
|
2023-04-07 06:58:17 +02:00
|
|
|
info->deadline_block = infinite_block_deadline(channel->peer->ld->topology);
|
2023-04-06 01:33:24 +02:00
|
|
|
create_onchain_tx(channel, &out, out_sats,
|
|
|
|
channel->channel_info.their_config.to_self_delay, 0,
|
2023-04-07 06:58:17 +02:00
|
|
|
sign_tx_to_us, info,
|
2023-04-06 01:33:24 +02:00
|
|
|
__func__);
|
|
|
|
}
|
|
|
|
|
2023-04-06 01:33:24 +02:00
|
|
|
static void handle_onchaind_spend_penalty(struct channel *channel,
|
|
|
|
const u8 *msg)
|
|
|
|
{
|
|
|
|
struct onchain_signing_info *info;
|
|
|
|
struct bitcoin_outpoint out;
|
|
|
|
struct amount_sat out_sats;
|
|
|
|
u8 *stack_elem;
|
|
|
|
|
|
|
|
info = new_signing_info(msg, channel, WIRE_ONCHAIND_SPEND_PENALTY);
|
|
|
|
/* We can always spend penalty txs immediately */
|
|
|
|
info->minblock = 0;
|
|
|
|
if (!fromwire_onchaind_spend_penalty(info, msg,
|
|
|
|
&out, &out_sats,
|
|
|
|
&info->u.spend_penalty.remote_per_commitment_secret,
|
|
|
|
&stack_elem,
|
|
|
|
&info->wscript)) {
|
|
|
|
channel_internal_error(channel, "Invalid onchaind_spend_penalty %s",
|
|
|
|
tal_hex(tmpctx, msg));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
/* info->stack_elem is const void * */
|
|
|
|
info->stack_elem = stack_elem;
|
|
|
|
|
|
|
|
/* FIXME: deadline for HTLCs is actually a bit longer, but for
|
|
|
|
* their output it's channel->our_config.to_self_delay after
|
|
|
|
* the commitment tx is mined. */
|
|
|
|
info->deadline_block = *channel->close_blockheight
|
|
|
|
+ channel->our_config.to_self_delay;
|
|
|
|
create_onchain_tx(channel, &out, out_sats,
|
|
|
|
0, 0,
|
2023-04-07 06:58:17 +02:00
|
|
|
sign_penalty, info,
|
2023-04-06 01:33:24 +02:00
|
|
|
__func__);
|
|
|
|
}
|
|
|
|
|
2023-04-06 01:33:25 +02:00
|
|
|
static void handle_onchaind_spend_fulfill(struct channel *channel,
|
|
|
|
const u8 *msg)
|
|
|
|
{
|
|
|
|
struct onchain_signing_info *info;
|
|
|
|
struct bitcoin_outpoint out;
|
|
|
|
struct amount_sat out_sats;
|
|
|
|
struct preimage preimage;
|
|
|
|
u64 htlc_id;
|
|
|
|
const bool anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS);
|
|
|
|
|
|
|
|
info = new_signing_info(msg, channel, WIRE_ONCHAIND_SPEND_FULFILL);
|
|
|
|
info->minblock = 0;
|
|
|
|
|
|
|
|
if (!fromwire_onchaind_spend_fulfill(info, msg,
|
|
|
|
&out, &out_sats,
|
|
|
|
&htlc_id,
|
|
|
|
&info->u.fulfill.remote_per_commitment_point,
|
|
|
|
&preimage,
|
|
|
|
&info->wscript)) {
|
|
|
|
channel_internal_error(channel, "Invalid onchaind_spend_fulfill %s",
|
|
|
|
tal_hex(tmpctx, msg));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
info->stack_elem = tal_dup(info, struct preimage, &preimage);
|
|
|
|
|
|
|
|
info->deadline_block = htlc_incoming_deadline(channel, htlc_id);
|
|
|
|
/* BOLT #3:
|
|
|
|
*
|
|
|
|
* Note that if `option_anchors` applies, the nSequence field of
|
|
|
|
* the spending input must be `1`.
|
|
|
|
*/
|
|
|
|
create_onchain_tx(channel, &out, out_sats,
|
|
|
|
anchor_outputs ? 1 : 0,
|
|
|
|
0,
|
2023-04-07 06:58:17 +02:00
|
|
|
sign_fulfill, info,
|
2023-04-06 01:33:25 +02:00
|
|
|
__func__);
|
|
|
|
}
|
|
|
|
|
2023-04-06 01:33:24 +02:00
|
|
|
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));
|
|
|
|
}
|
|
|
|
|
2023-04-06 01:33:25 +02:00
|
|
|
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));
|
|
|
|
}
|
|
|
|
|
2023-04-06 01:33:25 +02:00
|
|
|
static void handle_onchaind_spend_htlc_expired(struct channel *channel,
|
|
|
|
const u8 *msg)
|
|
|
|
{
|
|
|
|
struct onchain_signing_info *info;
|
|
|
|
struct bitcoin_outpoint out;
|
|
|
|
struct amount_sat out_sats;
|
|
|
|
u64 htlc_id;
|
2023-04-07 06:58:17 +02:00
|
|
|
u32 cltv_expiry;
|
2023-04-06 01:33:25 +02:00
|
|
|
const bool anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS);
|
|
|
|
|
|
|
|
info = new_signing_info(msg, channel, WIRE_ONCHAIND_SPEND_HTLC_EXPIRED);
|
|
|
|
|
|
|
|
/* BOLT #5:
|
|
|
|
*
|
|
|
|
* ## HTLC Output Handling: Remote Commitment, Local Offers
|
|
|
|
* ...
|
|
|
|
*
|
|
|
|
* - if the commitment transaction HTLC output has *timed out* AND NOT
|
|
|
|
* been *resolved*:
|
|
|
|
* - MUST *resolve* the output, by spending it to a convenient
|
|
|
|
* address.
|
|
|
|
*/
|
|
|
|
info->stack_elem = NULL;
|
|
|
|
|
|
|
|
if (!fromwire_onchaind_spend_htlc_expired(info, msg,
|
|
|
|
&out, &out_sats,
|
|
|
|
&htlc_id,
|
|
|
|
&cltv_expiry,
|
|
|
|
&info->u.htlc_expired.remote_per_commitment_point,
|
|
|
|
&info->wscript)) {
|
|
|
|
channel_internal_error(channel, "Invalid onchaind_spend_htlc_expired %s",
|
|
|
|
tal_hex(tmpctx, msg));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* nLocktime: we have to be *after* that block! */
|
|
|
|
info->minblock = cltv_expiry + 1;
|
|
|
|
|
|
|
|
/* We have to spend it before we can close incoming */
|
|
|
|
info->deadline_block = htlc_outgoing_incoming_deadline(channel, htlc_id);
|
|
|
|
create_onchain_tx(channel, &out, out_sats,
|
|
|
|
anchor_outputs ? 1 : 0,
|
|
|
|
cltv_expiry,
|
2023-04-07 06:58:17 +02:00
|
|
|
sign_htlc_expired, info,
|
2023-04-06 01:33:25 +02:00
|
|
|
__func__);
|
|
|
|
}
|
|
|
|
|
2018-03-05 17:40:50 +01:00
|
|
|
static unsigned int onchain_msg(struct subd *sd, const u8 *msg, const int *fds UNUSED)
|
2018-02-20 21:59:09 +01:00
|
|
|
{
|
2020-08-25 04:15:48 +02:00
|
|
|
enum onchaind_wire t = fromwire_peektype(msg);
|
2018-02-20 21:59:09 +01:00
|
|
|
|
|
|
|
switch (t) {
|
2020-08-25 04:15:48 +02:00
|
|
|
case WIRE_ONCHAIND_INIT_REPLY:
|
2018-02-20 21:59:09 +01:00
|
|
|
handle_onchain_init_reply(sd->channel, msg);
|
|
|
|
break;
|
|
|
|
|
2020-08-25 04:15:48 +02:00
|
|
|
case WIRE_ONCHAIND_UNWATCH_TX:
|
2018-02-20 21:59:09 +01:00
|
|
|
handle_onchain_unwatch_tx(sd->channel, msg);
|
|
|
|
break;
|
|
|
|
|
2020-08-25 04:15:48 +02:00
|
|
|
case WIRE_ONCHAIND_EXTRACTED_PREIMAGE:
|
2018-02-20 21:59:09 +01:00
|
|
|
handle_extracted_preimage(sd->channel, msg);
|
|
|
|
break;
|
|
|
|
|
2020-08-25 04:15:48 +02:00
|
|
|
case WIRE_ONCHAIND_MISSING_HTLC_OUTPUT:
|
2018-02-20 21:59:09 +01:00
|
|
|
handle_missing_htlc_output(sd->channel, msg);
|
|
|
|
break;
|
|
|
|
|
2020-08-25 04:15:48 +02:00
|
|
|
case WIRE_ONCHAIND_HTLC_TIMEOUT:
|
2018-02-20 21:59:09 +01:00
|
|
|
handle_onchain_htlc_timeout(sd->channel, msg);
|
|
|
|
break;
|
|
|
|
|
2020-08-25 04:15:48 +02:00
|
|
|
case WIRE_ONCHAIND_ALL_IRREVOCABLY_RESOLVED:
|
2018-02-20 21:59:09 +01:00
|
|
|
handle_irrevocably_resolved(sd->channel, msg);
|
|
|
|
break;
|
|
|
|
|
2020-08-25 04:15:48 +02:00
|
|
|
case WIRE_ONCHAIND_ADD_UTXO:
|
2018-02-20 21:59:09 +01:00
|
|
|
onchain_add_utxo(sd->channel, msg);
|
|
|
|
break;
|
|
|
|
|
2020-08-25 04:15:48 +02:00
|
|
|
case WIRE_ONCHAIND_ANNOTATE_TXIN:
|
2019-10-04 12:27:48 +02:00
|
|
|
onchain_annotate_txin(sd->channel, msg);
|
|
|
|
break;
|
|
|
|
|
2020-08-25 04:15:48 +02:00
|
|
|
case WIRE_ONCHAIND_ANNOTATE_TXOUT:
|
2019-10-04 12:27:48 +02:00
|
|
|
onchain_annotate_txout(sd->channel, msg);
|
2019-05-27 13:06:02 +02:00
|
|
|
break;
|
|
|
|
|
2020-08-25 04:15:48 +02:00
|
|
|
case WIRE_ONCHAIND_NOTIFY_COIN_MVT:
|
2020-04-02 04:16:32 +02:00
|
|
|
handle_onchain_log_coin_move(sd->channel, msg);
|
|
|
|
break;
|
|
|
|
|
2023-04-06 01:33:24 +02:00
|
|
|
case WIRE_ONCHAIND_SPEND_TO_US:
|
|
|
|
handle_onchaind_spend_to_us(sd->channel, msg);
|
|
|
|
break;
|
|
|
|
|
2023-04-06 01:33:24 +02:00
|
|
|
case WIRE_ONCHAIND_SPEND_PENALTY:
|
|
|
|
handle_onchaind_spend_penalty(sd->channel, msg);
|
|
|
|
break;
|
|
|
|
|
2023-04-06 01:33:24 +02:00
|
|
|
case WIRE_ONCHAIND_SPEND_HTLC_SUCCESS:
|
|
|
|
handle_onchaind_spend_htlc_success(sd->channel, msg);
|
|
|
|
break;
|
|
|
|
|
2023-04-06 01:33:25 +02:00
|
|
|
case WIRE_ONCHAIND_SPEND_HTLC_TIMEOUT:
|
|
|
|
handle_onchaind_spend_htlc_timeout(sd->channel, msg);
|
|
|
|
break;
|
|
|
|
|
2023-04-06 01:33:25 +02:00
|
|
|
case WIRE_ONCHAIND_SPEND_FULFILL:
|
|
|
|
handle_onchaind_spend_fulfill(sd->channel, msg);
|
|
|
|
break;
|
|
|
|
|
2023-04-06 01:33:25 +02:00
|
|
|
case WIRE_ONCHAIND_SPEND_HTLC_EXPIRED:
|
|
|
|
handle_onchaind_spend_htlc_expired(sd->channel, msg);
|
|
|
|
break;
|
|
|
|
|
2018-02-20 21:59:09 +01:00
|
|
|
/* We send these, not receive them */
|
2020-08-25 04:15:48 +02:00
|
|
|
case WIRE_ONCHAIND_INIT:
|
|
|
|
case WIRE_ONCHAIND_SPENT:
|
|
|
|
case WIRE_ONCHAIND_DEPTH:
|
2021-10-13 05:45:36 +02:00
|
|
|
case WIRE_ONCHAIND_HTLCS:
|
2020-08-25 04:15:48 +02:00
|
|
|
case WIRE_ONCHAIND_KNOWN_PREIMAGE:
|
2023-04-06 01:33:24 +02:00
|
|
|
case WIRE_ONCHAIND_SPEND_CREATED:
|
2020-08-25 04:15:48 +02:00
|
|
|
case WIRE_ONCHAIND_DEV_MEMLEAK:
|
|
|
|
case WIRE_ONCHAIND_DEV_MEMLEAK_REPLY:
|
2018-02-20 21:59:09 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Only error onchaind can get is if it dies. */
|
|
|
|
static void onchain_error(struct channel *channel,
|
2022-01-11 02:13:59 +01:00
|
|
|
struct peer_fd *pps UNUSED,
|
2018-03-05 17:40:50 +01:00
|
|
|
const struct channel_id *channel_id UNUSED,
|
2018-02-20 21:59:09 +01:00
|
|
|
const char *desc,
|
2021-02-02 13:47:01 +01:00
|
|
|
bool warning UNUSED,
|
2018-03-05 17:40:50 +01:00
|
|
|
const u8 *err_for_them UNUSED)
|
2018-02-20 21:59:09 +01:00
|
|
|
{
|
2022-01-30 04:37:30 +01:00
|
|
|
channel_set_owner(channel, NULL);
|
|
|
|
|
|
|
|
/* This happens on shutdown: fine */
|
|
|
|
if (channel->peer->ld->state == LD_STATE_SHUTDOWN)
|
|
|
|
return;
|
|
|
|
|
2018-02-20 21:59:09 +01:00
|
|
|
/* FIXME: re-launch? */
|
|
|
|
log_broken(channel->log, "%s", desc);
|
2018-03-03 19:59:07 +01:00
|
|
|
channel_set_billboard(channel, true, desc);
|
2018-02-20 21:59:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* With a reorg, this can get called multiple times; each time we'll kill
|
|
|
|
* onchaind (like any other owner), and restart */
|
2018-04-16 13:20:45 +02:00
|
|
|
enum watch_result onchaind_funding_spent(struct channel *channel,
|
|
|
|
const struct bitcoin_tx *tx,
|
2021-12-01 17:24:31 +01:00
|
|
|
u32 blockheight)
|
2018-02-20 21:59:09 +01:00
|
|
|
{
|
2018-03-07 01:06:07 +01:00
|
|
|
u8 *msg;
|
2020-05-26 05:39:40 +02:00
|
|
|
struct bitcoin_txid our_last_txid;
|
2018-02-20 21:59:09 +01:00
|
|
|
struct lightningd *ld = channel->peer->ld;
|
2018-03-07 01:06:07 +01:00
|
|
|
struct pubkey final_key;
|
2018-07-23 04:23:02 +02:00
|
|
|
int hsmfd;
|
feat: adds state change cause and message
This adds a `state_change` 'cause' to a channel.
A 'cause' is some initial 'reason' a channel was created or closed by:
/* Anything other than the reasons below. Should not happen. */
REASON_UNKNOWN,
/* Unconscious internal reasons, e.g. dev fail of a channel. */
REASON_LOCAL,
/* The operator or a plugin opened or closed a channel by intention. */
REASON_USER,
/* The remote closed or funded a channel with us by intention. */
REASON_REMOTE,
/* E.g. We need to close a channel because of bad signatures and such. */
REASON_PROTOCOL,
/* A channel was closed onchain, while we were offline. */
/* Note: This is very likely a conscious remote decision. */
REASON_ONCHAIN
If a 'cause' is known and a subsequent state change is made with
`REASON_UNKNOWN` the preceding cause will be used as reason, since a lot
(all `REASON_UNKNOWN`) state changes are a subsequent consequences of a prior
cause: local, user, remote, protocol or onchain.
Changelog-Added: Plugins: Channel closure resaon/cause to channel_state_changed notification
2020-10-28 11:46:12 +01:00
|
|
|
enum state_change reason;
|
2018-02-20 21:59:09 +01:00
|
|
|
|
feat: adds state change cause and message
This adds a `state_change` 'cause' to a channel.
A 'cause' is some initial 'reason' a channel was created or closed by:
/* Anything other than the reasons below. Should not happen. */
REASON_UNKNOWN,
/* Unconscious internal reasons, e.g. dev fail of a channel. */
REASON_LOCAL,
/* The operator or a plugin opened or closed a channel by intention. */
REASON_USER,
/* The remote closed or funded a channel with us by intention. */
REASON_REMOTE,
/* E.g. We need to close a channel because of bad signatures and such. */
REASON_PROTOCOL,
/* A channel was closed onchain, while we were offline. */
/* Note: This is very likely a conscious remote decision. */
REASON_ONCHAIN
If a 'cause' is known and a subsequent state change is made with
`REASON_UNKNOWN` the preceding cause will be used as reason, since a lot
(all `REASON_UNKNOWN`) state changes are a subsequent consequences of a prior
cause: local, user, remote, protocol or onchain.
Changelog-Added: Plugins: Channel closure resaon/cause to channel_state_changed notification
2020-10-28 11:46:12 +01:00
|
|
|
/* use REASON_ONCHAIN or closer's reason, if known */
|
|
|
|
reason = REASON_ONCHAIN;
|
|
|
|
if (channel->closer != NUM_SIDES)
|
|
|
|
reason = REASON_UNKNOWN; /* will use last cause as reason */
|
|
|
|
|
2022-09-12 23:19:11 +02:00
|
|
|
channel_fail_permanent(channel, reason,
|
|
|
|
"Funding transaction spent");
|
2018-02-20 21:59:09 +01:00
|
|
|
|
2022-07-19 09:34:38 +02:00
|
|
|
/* If we haven't posted the open event yet, post an open */
|
2022-09-10 04:10:31 +02:00
|
|
|
if (!channel->scid || !channel->remote_channel_ready) {
|
2022-07-19 09:34:38 +02:00
|
|
|
u32 blkh;
|
2022-07-19 21:35:56 +02:00
|
|
|
/* Blockheight will be zero if it's not in chain */
|
2022-07-19 09:34:38 +02:00
|
|
|
blkh = wallet_transaction_height(channel->peer->ld->wallet,
|
|
|
|
&channel->funding.txid);
|
2022-07-19 21:35:56 +02:00
|
|
|
channel_record_open(channel, blkh, true);
|
2022-07-19 09:34:38 +02:00
|
|
|
}
|
|
|
|
|
2023-04-06 01:33:24 +02:00
|
|
|
tal_free(channel->close_blockheight);
|
|
|
|
channel->close_blockheight = tal_dup(channel, u32, &blockheight);
|
2022-07-19 09:34:38 +02:00
|
|
|
|
2018-02-20 21:59:09 +01:00
|
|
|
/* We could come from almost any state. */
|
feat: adds state change cause and message
This adds a `state_change` 'cause' to a channel.
A 'cause' is some initial 'reason' a channel was created or closed by:
/* Anything other than the reasons below. Should not happen. */
REASON_UNKNOWN,
/* Unconscious internal reasons, e.g. dev fail of a channel. */
REASON_LOCAL,
/* The operator or a plugin opened or closed a channel by intention. */
REASON_USER,
/* The remote closed or funded a channel with us by intention. */
REASON_REMOTE,
/* E.g. We need to close a channel because of bad signatures and such. */
REASON_PROTOCOL,
/* A channel was closed onchain, while we were offline. */
/* Note: This is very likely a conscious remote decision. */
REASON_ONCHAIN
If a 'cause' is known and a subsequent state change is made with
`REASON_UNKNOWN` the preceding cause will be used as reason, since a lot
(all `REASON_UNKNOWN`) state changes are a subsequent consequences of a prior
cause: local, user, remote, protocol or onchain.
Changelog-Added: Plugins: Channel closure resaon/cause to channel_state_changed notification
2020-10-28 11:46:12 +01:00
|
|
|
/* NOTE(mschmoock) above comment is wrong, since we failed above! */
|
|
|
|
channel_set_state(channel,
|
|
|
|
channel->state,
|
|
|
|
FUNDING_SPEND_SEEN,
|
|
|
|
reason,
|
2022-07-19 09:34:39 +02:00
|
|
|
tal_fmt(tmpctx, "Onchain funding spend"));
|
2018-02-20 21:59:09 +01:00
|
|
|
|
2018-07-23 04:23:02 +02:00
|
|
|
hsmfd = hsm_get_client_fd(ld, &channel->peer->id,
|
|
|
|
channel->dbid,
|
2018-07-23 04:23:03 +02:00
|
|
|
HSM_CAP_SIGN_ONCHAIN_TX
|
|
|
|
| HSM_CAP_COMMITMENT_POINT);
|
2018-07-23 04:23:02 +02:00
|
|
|
|
2022-03-29 01:49:23 +02:00
|
|
|
channel_set_owner(channel, new_channel_subd(channel, ld,
|
2018-02-20 21:59:09 +01:00
|
|
|
"lightning_onchaind",
|
2021-01-20 02:51:15 +01:00
|
|
|
channel,
|
2020-12-01 21:49:35 +01:00
|
|
|
&channel->peer->id,
|
2018-04-26 06:51:01 +02:00
|
|
|
channel->log, false,
|
2020-08-25 04:15:48 +02:00
|
|
|
onchaind_wire_name,
|
2018-02-20 21:59:09 +01:00
|
|
|
onchain_msg,
|
|
|
|
onchain_error,
|
2018-02-23 06:53:47 +01:00
|
|
|
channel_set_billboard,
|
2018-07-23 04:23:02 +02:00
|
|
|
take(&hsmfd),
|
2019-07-25 04:47:34 +02:00
|
|
|
NULL));
|
2018-02-20 21:59:09 +01:00
|
|
|
|
|
|
|
if (!channel->owner) {
|
|
|
|
log_broken(channel->log, "Could not subdaemon onchain: %s",
|
|
|
|
strerror(errno));
|
|
|
|
return KEEP_WATCHING;
|
|
|
|
}
|
|
|
|
|
2023-03-21 04:58:15 +01:00
|
|
|
bip32_pubkey(ld, &final_key, channel->final_key_idx);
|
|
|
|
|
2021-12-23 21:16:35 +01:00
|
|
|
struct ext_key final_wallet_ext_key;
|
|
|
|
if (bip32_key_from_parent(
|
2023-03-21 04:58:15 +01:00
|
|
|
ld->bip32_base,
|
2021-12-23 21:16:35 +01:00
|
|
|
channel->final_key_idx,
|
|
|
|
BIP32_FLAG_KEY_PUBLIC,
|
|
|
|
&final_wallet_ext_key) != WALLY_OK) {
|
|
|
|
log_broken(channel->log, "Could not derive final_wallet_ext_key %"PRIu64,
|
|
|
|
channel->final_key_idx);
|
|
|
|
return KEEP_WATCHING;
|
|
|
|
}
|
2022-06-24 03:14:11 +02:00
|
|
|
|
|
|
|
/* This could be a mutual close, but it doesn't matter.
|
|
|
|
* We don't need this for stub channels as well */
|
|
|
|
if (!is_stub_scid(channel->scid))
|
|
|
|
bitcoin_txid(channel->last_tx, &our_last_txid);
|
|
|
|
else
|
|
|
|
/* Dummy txid for stub channel to make valgrind happy. */
|
|
|
|
bitcoin_txid_from_hex("80cea306607b708a03a1854520729d"
|
|
|
|
"a884e4317b7b51f3d4a622f88176f5e034",
|
|
|
|
64,
|
|
|
|
&our_last_txid);
|
2018-02-20 21:59:09 +01:00
|
|
|
|
2021-06-04 07:13:47 +02:00
|
|
|
log_debug(channel->log, "channel->static_remotekey_start[LOCAL] %"PRIu64,
|
|
|
|
channel->static_remotekey_start[LOCAL]);
|
|
|
|
|
2020-08-25 04:15:48 +02:00
|
|
|
msg = towire_onchaind_init(channel,
|
2018-07-23 04:23:03 +02:00
|
|
|
&channel->their_shachain.chain,
|
2019-09-25 22:38:45 +02:00
|
|
|
chainparams,
|
2021-10-13 05:45:36 +02:00
|
|
|
channel->funding_sats,
|
2020-04-02 04:21:22 +02:00
|
|
|
channel->our_msat,
|
2018-02-20 21:59:09 +01:00
|
|
|
&channel->channel_info.old_remote_per_commit,
|
|
|
|
&channel->channel_info.remote_per_commit,
|
|
|
|
/* BOLT #2:
|
|
|
|
* `to_self_delay` is the number of blocks
|
2018-06-17 12:13:44 +02:00
|
|
|
* that the other node's to-self outputs
|
2018-02-20 21:59:09 +01:00
|
|
|
* 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,
|
2019-02-21 04:45:55 +01:00
|
|
|
channel->our_config.dust_limit,
|
2018-02-20 21:59:09 +01:00
|
|
|
&our_last_txid,
|
2019-09-29 10:53:26 +02:00
|
|
|
channel->shutdown_scriptpubkey[LOCAL],
|
2019-09-29 09:35:45 +02:00
|
|
|
channel->shutdown_scriptpubkey[REMOTE],
|
2021-12-23 21:16:35 +01:00
|
|
|
channel->final_key_idx,
|
|
|
|
&final_wallet_ext_key,
|
2018-03-07 01:06:07 +01:00
|
|
|
&final_key,
|
2019-09-09 18:11:24 +02:00
|
|
|
channel->opener,
|
2018-07-23 04:23:03 +02:00
|
|
|
&channel->local_basepoints,
|
2018-07-09 13:17:59 +02:00
|
|
|
&channel->channel_info.theirbase,
|
2020-05-26 05:39:40 +02:00
|
|
|
tx_parts_from_wally_tx(tmpctx, tx->wtx, -1, -1),
|
|
|
|
tx->wtx->locktime,
|
2018-04-16 13:20:45 +02:00
|
|
|
blockheight,
|
2018-02-20 21:59:09 +01:00
|
|
|
/* FIXME: config for 'reasonable depth' */
|
|
|
|
3,
|
|
|
|
channel->last_htlc_sigs,
|
2018-04-03 09:19:39 +02:00
|
|
|
channel->min_possible_feerate,
|
2018-08-17 07:06:36 +02:00
|
|
|
channel->max_possible_feerate,
|
2019-09-10 04:23:27 +02:00
|
|
|
channel->future_per_commitment_point,
|
2020-08-14 03:30:42 +02:00
|
|
|
&channel->local_funding_pubkey,
|
|
|
|
&channel->channel_info.remote_fundingkey,
|
2021-06-04 07:13:47 +02:00
|
|
|
channel->static_remotekey_start[LOCAL],
|
|
|
|
channel->static_remotekey_start[REMOTE],
|
2021-09-09 07:29:35 +02:00
|
|
|
channel_has(channel, OPT_ANCHOR_OUTPUTS),
|
2020-09-08 05:20:02 +02:00
|
|
|
feerate_min(ld, NULL));
|
2018-02-20 21:59:09 +01:00
|
|
|
subd_send_msg(channel->owner, take(msg));
|
|
|
|
|
|
|
|
watch_tx_and_outputs(channel, tx);
|
|
|
|
|
|
|
|
/* We keep watching until peer finally deleted, for reorgs. */
|
|
|
|
return KEEP_WATCHING;
|
|
|
|
}
|
2018-04-17 15:31:30 +02:00
|
|
|
|
|
|
|
void onchaind_replay_channels(struct lightningd *ld)
|
|
|
|
{
|
|
|
|
u32 *onchaind_ids;
|
|
|
|
struct channeltx *txs;
|
|
|
|
struct channel *chan;
|
|
|
|
|
|
|
|
db_begin_transaction(ld->wallet->db);
|
|
|
|
onchaind_ids = wallet_onchaind_channels(ld->wallet, ld);
|
|
|
|
|
|
|
|
for (size_t i = 0; i < tal_count(onchaind_ids); i++) {
|
|
|
|
log_info(ld->log, "Restarting onchaind for channel %d",
|
|
|
|
onchaind_ids[i]);
|
|
|
|
|
|
|
|
txs = wallet_channeltxs_get(ld->wallet, onchaind_ids,
|
|
|
|
onchaind_ids[i]);
|
|
|
|
chan = channel_by_dbid(ld, onchaind_ids[i]);
|
|
|
|
|
|
|
|
for (size_t j = 0; j < tal_count(txs); j++) {
|
2020-08-25 04:15:48 +02:00
|
|
|
if (txs[j].type == WIRE_ONCHAIND_INIT) {
|
2018-04-17 15:31:30 +02:00
|
|
|
onchaind_funding_spent(chan, txs[j].tx,
|
2021-12-01 17:24:31 +01:00
|
|
|
txs[j].blockheight);
|
2018-04-17 15:31:30 +02:00
|
|
|
|
2020-08-25 04:15:48 +02:00
|
|
|
} else if (txs[j].type == WIRE_ONCHAIND_SPENT) {
|
2018-04-17 15:31:30 +02:00
|
|
|
onchain_txo_spent(chan, txs[j].tx,
|
|
|
|
txs[j].input_num,
|
2021-12-01 17:24:31 +01:00
|
|
|
txs[j].blockheight);
|
2018-04-17 15:31:30 +02:00
|
|
|
|
2020-08-25 04:15:48 +02:00
|
|
|
} else if (txs[j].type == WIRE_ONCHAIND_DEPTH) {
|
2018-04-17 15:31:30 +02:00
|
|
|
onchain_tx_depth(chan, &txs[j].txid,
|
2021-12-01 17:24:31 +01:00
|
|
|
txs[j].depth);
|
2018-04-17 15:31:30 +02:00
|
|
|
|
|
|
|
} else {
|
|
|
|
fatal("unknown message of type %d during "
|
|
|
|
"onchaind replay",
|
|
|
|
txs[j].type);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
tal_free(txs);
|
|
|
|
}
|
|
|
|
tal_free(onchaind_ids);
|
|
|
|
|
|
|
|
db_commit_transaction(ld->wallet->db);
|
|
|
|
}
|