2018-06-20 08:50:44 +02:00
|
|
|
#include <bitcoin/feerate.h>
|
2020-05-27 03:37:44 +02:00
|
|
|
#include <bitcoin/psbt.h>
|
2017-08-23 03:52:17 +02:00
|
|
|
#include <bitcoin/script.h>
|
2020-12-03 02:22:01 +01:00
|
|
|
#include <ccan/asort/asort.h>
|
2017-08-23 03:52:17 +02:00
|
|
|
#include <ccan/crypto/shachain/shachain.h>
|
|
|
|
#include <ccan/mem/mem.h>
|
|
|
|
#include <ccan/tal/str/str.h>
|
2019-09-26 21:07:20 +02:00
|
|
|
#include <common/amount.h>
|
2020-04-02 04:16:32 +02:00
|
|
|
#include <common/coin_mvt.h>
|
2017-08-28 18:02:01 +02:00
|
|
|
#include <common/derive_basepoints.h>
|
|
|
|
#include <common/htlc_tx.h>
|
|
|
|
#include <common/initial_commit_tx.h>
|
2017-08-28 18:05:01 +02:00
|
|
|
#include <common/key_derive.h>
|
|
|
|
#include <common/keyset.h>
|
2021-06-16 19:44:51 +02:00
|
|
|
#include <common/lease_rates.h>
|
2018-11-22 03:17:29 +01:00
|
|
|
#include <common/memleak.h>
|
2020-09-08 05:22:41 +02:00
|
|
|
#include <common/overflows.h>
|
2018-02-23 06:53:47 +01:00
|
|
|
#include <common/peer_billboard.h>
|
2017-08-28 18:05:01 +02:00
|
|
|
#include <common/status.h>
|
2018-01-08 11:01:09 +01:00
|
|
|
#include <common/subdaemon.h>
|
2017-08-28 18:02:01 +02:00
|
|
|
#include <common/type_to_string.h>
|
|
|
|
#include <common/utils.h>
|
|
|
|
#include <common/version.h>
|
2019-05-27 13:04:10 +02:00
|
|
|
#include <common/wallet.h>
|
2017-08-23 03:52:17 +02:00
|
|
|
#include <errno.h>
|
2020-08-25 03:55:38 +02:00
|
|
|
#include <hsmd/hsmd_wiregen.h>
|
2017-08-23 03:52:17 +02:00
|
|
|
#include <inttypes.h>
|
2018-02-19 02:06:14 +01:00
|
|
|
#include <lightningd/channel_state.h>
|
2017-08-29 06:12:04 +02:00
|
|
|
#include <onchaind/onchain_types.h>
|
2020-08-25 04:15:48 +02:00
|
|
|
#include <onchaind/onchaind_wiregen.h>
|
2017-08-23 03:52:17 +02:00
|
|
|
#include <stdio.h>
|
2017-08-28 18:05:01 +02:00
|
|
|
#include <unistd.h>
|
2017-08-23 03:52:17 +02:00
|
|
|
#include <wire/wire_sync.h>
|
2020-10-22 01:51:08 +02:00
|
|
|
#include "onchain_types_names_gen.h"
|
2017-08-23 03:52:17 +02:00
|
|
|
|
|
|
|
/* stdin == requests */
|
|
|
|
#define REQ_FD STDIN_FILENO
|
2018-07-23 04:23:02 +02:00
|
|
|
#define HSM_FD 3
|
2021-06-16 20:09:32 +02:00
|
|
|
#define max(a, b) ((a) > (b) ? (a) : (b))
|
2017-08-23 03:52:17 +02:00
|
|
|
|
2017-09-16 01:36:06 +02:00
|
|
|
/* Required in various places: keys for commitment transaction. */
|
|
|
|
static const struct keyset *keyset;
|
|
|
|
|
2018-07-23 04:23:02 +02:00
|
|
|
/* IFF it's their commitment tx: HSM can't derive their per-commitment point! */
|
|
|
|
static const struct pubkey *remote_per_commitment_point;
|
|
|
|
|
2018-07-23 04:23:02 +02:00
|
|
|
/* The commitment number we're dealing with (if not mutual close) */
|
|
|
|
static u64 commit_num;
|
|
|
|
|
2020-03-10 14:11:47 +01:00
|
|
|
/* The feerate for the transaction spending our delayed output. */
|
|
|
|
static u32 delayed_to_us_feerate;
|
|
|
|
|
|
|
|
/* The feerate for transactions spending HTLC outputs. */
|
|
|
|
static u32 htlc_feerate;
|
|
|
|
|
|
|
|
/* The feerate for transactions spending from revoked transactions. */
|
|
|
|
static u32 penalty_feerate;
|
2017-09-16 01:36:06 +02:00
|
|
|
|
2018-04-03 06:30:48 +02:00
|
|
|
/* Min and max feerates we ever used */
|
2018-04-03 06:31:48 +02:00
|
|
|
static u32 min_possible_feerate, max_possible_feerate;
|
2018-04-03 06:30:48 +02:00
|
|
|
|
2017-09-16 01:36:06 +02:00
|
|
|
/* The dust limit to use when we generate transactions. */
|
2019-02-21 04:45:55 +01:00
|
|
|
static struct amount_sat dust_limit;
|
2017-09-16 01:36:06 +02:00
|
|
|
|
2017-09-16 01:37:06 +02:00
|
|
|
/* The CSV delays for each side. */
|
|
|
|
static u32 to_self_delay[NUM_SIDES];
|
|
|
|
|
2017-09-16 01:38:06 +02:00
|
|
|
/* Where we send money to (our wallet) */
|
|
|
|
static struct pubkey our_wallet_pubkey;
|
|
|
|
|
2018-07-23 04:23:02 +02:00
|
|
|
/* Their revocation secret (only if they cheated). */
|
|
|
|
static const struct secret *remote_per_commitment_secret;
|
2017-09-26 23:02:37 +02:00
|
|
|
|
|
|
|
/* one value is useful for a few witness scripts */
|
|
|
|
static const u8 ONE = 0x1;
|
|
|
|
|
2017-09-26 23:02:47 +02:00
|
|
|
/* When to tell master about HTLCs which are missing/timed out */
|
|
|
|
static u32 reasonable_depth;
|
2017-09-26 23:02:47 +02:00
|
|
|
|
|
|
|
/* The messages to send at that depth. */
|
|
|
|
static u8 **missing_htlc_msgs;
|
|
|
|
|
2020-04-02 04:21:22 +02:00
|
|
|
/* Our recorded channel balance at 'chain time' */
|
|
|
|
static struct amount_msat our_msat;
|
|
|
|
|
2020-08-14 03:30:42 +02:00
|
|
|
/* Needed for anchor outputs */
|
|
|
|
static struct pubkey funding_pubkey[NUM_SIDES];
|
|
|
|
|
2021-06-04 07:13:47 +02:00
|
|
|
/* At what commit number does option_static_remotekey apply? */
|
|
|
|
static u64 static_remotekey_start[NUM_SIDES];
|
2020-08-13 19:41:02 +02:00
|
|
|
|
|
|
|
/* Does option_anchor_outputs apply to this commitment tx? */
|
|
|
|
static bool option_anchor_outputs;
|
2019-09-10 04:23:27 +02:00
|
|
|
|
2020-09-08 05:20:02 +02:00
|
|
|
/* The minimum relay feerate acceptable to the fullnode. */
|
|
|
|
static u32 min_relay_feerate;
|
|
|
|
|
2017-08-23 03:52:17 +02:00
|
|
|
/* If we broadcast a tx, or need a delay to resolve the output. */
|
|
|
|
struct proposed_resolution {
|
|
|
|
/* This can be NULL if our proposal is to simply ignore it after depth */
|
|
|
|
const struct bitcoin_tx *tx;
|
|
|
|
/* Non-zero if this is CSV-delayed. */
|
|
|
|
u32 depth_required;
|
|
|
|
enum tx_type tx_type;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* How it actually got resolved. */
|
|
|
|
struct resolution {
|
2017-12-18 07:41:52 +01:00
|
|
|
struct bitcoin_txid txid;
|
2017-08-23 03:52:17 +02:00
|
|
|
unsigned int depth;
|
|
|
|
enum tx_type tx_type;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct tracked_output {
|
|
|
|
enum tx_type tx_type;
|
2017-12-18 07:41:52 +01:00
|
|
|
struct bitcoin_txid txid;
|
2017-08-23 03:52:17 +02:00
|
|
|
u32 tx_blockheight;
|
2018-02-23 06:53:47 +01:00
|
|
|
/* FIXME: Convert all depths to blocknums, then just get new blk msgs */
|
|
|
|
u32 depth;
|
2017-08-23 03:52:17 +02:00
|
|
|
u32 outnum;
|
2019-02-21 04:45:55 +01:00
|
|
|
struct amount_sat sat;
|
2017-08-23 03:52:17 +02:00
|
|
|
enum output_type output_type;
|
|
|
|
|
2018-11-22 03:17:29 +01:00
|
|
|
/* If it is an HTLC, this is set, wscript is non-NULL. */
|
|
|
|
struct htlc_stub htlc;
|
2017-09-20 06:45:41 +02:00
|
|
|
const u8 *wscript;
|
|
|
|
|
|
|
|
/* If it's an HTLC off our unilateral, this is their sig for htlc_tx */
|
2018-12-03 00:15:06 +01:00
|
|
|
const struct bitcoin_signature *remote_htlc_sig;
|
2017-09-20 06:45:41 +02:00
|
|
|
|
2017-08-23 03:52:17 +02:00
|
|
|
/* Our proposed solution (if any) */
|
|
|
|
struct proposed_resolution *proposal;
|
|
|
|
|
|
|
|
/* If it is resolved. */
|
|
|
|
struct resolution *resolved;
|
2019-07-30 16:14:43 +02:00
|
|
|
|
2020-04-02 04:31:28 +02:00
|
|
|
/* stashed so we can pass it along to the coin ledger */
|
2020-04-15 05:08:06 +02:00
|
|
|
struct sha256 payment_hash;
|
2017-08-23 03:52:17 +02:00
|
|
|
};
|
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
/* helper to compare output script with our tal'd script */
|
|
|
|
static bool wally_tx_output_scripteq(const struct wally_tx_output *out,
|
|
|
|
const u8 *script)
|
|
|
|
{
|
|
|
|
return memeq(out->script, out->script_len, script, tal_bytelen(script));
|
|
|
|
}
|
|
|
|
|
2020-12-03 02:22:01 +01:00
|
|
|
/* The feerate for the HTLC txs (which we grind) are the same as the
|
|
|
|
* feerate for the main tx. However, there may be dust HTLCs which
|
|
|
|
* were added to the fee, so we can only estimate a maximum feerate */
|
|
|
|
static void trim_maximum_feerate(struct amount_sat funding,
|
|
|
|
const struct tx_parts *commitment)
|
|
|
|
{
|
|
|
|
size_t weight;
|
|
|
|
struct amount_sat fee = funding;
|
|
|
|
|
|
|
|
/* FIXME: This doesn't work for elements? */
|
|
|
|
if (chainparams->is_elements)
|
|
|
|
return;
|
|
|
|
|
|
|
|
weight = bitcoin_tx_core_weight(tal_count(commitment->inputs),
|
|
|
|
tal_count(commitment->outputs));
|
|
|
|
|
|
|
|
/* BOLT #3:
|
|
|
|
* ## Commitment Transaction
|
|
|
|
*...
|
|
|
|
* * `txin[0]` script bytes: 0
|
|
|
|
* * `txin[0]` witness: `0 <signature_for_pubkey1> <signature_for_pubkey2>`
|
|
|
|
*/
|
|
|
|
/* Account for witness (1 byte count + 1 empty + sig + sig) */
|
|
|
|
assert(tal_count(commitment->inputs) == 1);
|
|
|
|
weight += bitcoin_tx_input_weight(false, 1 + 1 + 2 * bitcoin_tx_input_sig_weight());
|
|
|
|
|
|
|
|
for (size_t i = 0; i < tal_count(commitment->outputs); i++) {
|
|
|
|
struct amount_asset amt;
|
|
|
|
weight += bitcoin_tx_output_weight(commitment->outputs[i]
|
|
|
|
->script_len);
|
|
|
|
|
|
|
|
amt = wally_tx_output_get_amount(commitment->outputs[i]);
|
|
|
|
if (!amount_asset_is_main(&amt))
|
|
|
|
continue;
|
|
|
|
if (!amount_sat_sub(&fee, fee, amount_asset_to_sat(&amt))) {
|
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
|
|
"Unable to subtract fee");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
status_debug("reducing max_possible_feerate from %u...",
|
|
|
|
max_possible_feerate);
|
|
|
|
/* This is naive, but simple. */
|
|
|
|
while (amount_sat_greater(amount_tx_fee(max_possible_feerate, weight),
|
|
|
|
fee))
|
|
|
|
max_possible_feerate--;
|
|
|
|
status_debug("... to %u", max_possible_feerate);
|
|
|
|
}
|
|
|
|
|
2020-04-02 04:16:32 +02:00
|
|
|
static void send_coin_mvt(struct chain_coin_mvt *mvt TAKES)
|
|
|
|
{
|
|
|
|
wire_sync_write(REQ_FD,
|
2020-08-25 04:15:48 +02:00
|
|
|
take(towire_onchaind_notify_coin_mvt(NULL, mvt)));
|
2020-04-02 04:16:32 +02:00
|
|
|
|
|
|
|
if (taken(mvt))
|
|
|
|
tal_free(mvt);
|
|
|
|
}
|
|
|
|
|
2020-04-02 04:48:39 +02:00
|
|
|
static void record_their_successful_cheat(const struct bitcoin_txid *txid,
|
2020-04-03 23:52:35 +02:00
|
|
|
u32 blockheight,
|
2020-04-02 04:48:39 +02:00
|
|
|
struct tracked_output *out)
|
|
|
|
{
|
|
|
|
struct chain_coin_mvt *mvt;
|
|
|
|
/* They successfully spent a delayed_to_them output
|
|
|
|
* that we were expecting to revoke */
|
2020-04-15 05:08:06 +02:00
|
|
|
mvt = new_coin_penalty_sat(NULL, NULL,
|
|
|
|
txid, &out->txid, out->outnum,
|
2020-04-15 05:40:28 +02:00
|
|
|
blockheight, out->sat);
|
2020-04-02 04:48:39 +02:00
|
|
|
|
|
|
|
send_coin_mvt(take(mvt));
|
|
|
|
}
|
|
|
|
|
2020-04-02 04:16:32 +02:00
|
|
|
static void record_htlc_fulfilled(const struct bitcoin_txid *txid,
|
|
|
|
struct tracked_output *out,
|
2020-04-03 23:52:35 +02:00
|
|
|
u32 blockheight,
|
2020-04-02 04:16:32 +02:00
|
|
|
bool we_fulfilled)
|
|
|
|
{
|
|
|
|
struct chain_coin_mvt *mvt;
|
|
|
|
|
|
|
|
/* we're recording the *deposit* of a utxo which contained channel
|
|
|
|
* funds (htlc).
|
|
|
|
*
|
|
|
|
* since we really don't know if this was a 'routed' or 'destination'
|
|
|
|
* htlc here, we record it as a 'deposit/withdrawal' type */
|
2020-04-15 05:08:06 +02:00
|
|
|
mvt = new_coin_onchain_htlc_sat(NULL, NULL, txid, &out->txid,
|
|
|
|
out->outnum, out->payment_hash,
|
2020-04-15 05:40:28 +02:00
|
|
|
blockheight, out->sat, we_fulfilled);
|
2020-04-02 04:16:32 +02:00
|
|
|
|
|
|
|
send_coin_mvt(take(mvt));
|
|
|
|
}
|
|
|
|
|
2020-04-02 04:35:52 +02:00
|
|
|
static void update_ledger_chain_fees_msat(const struct bitcoin_txid *txid,
|
2020-04-03 23:52:35 +02:00
|
|
|
u32 blockheight,
|
2020-04-02 04:35:52 +02:00
|
|
|
struct amount_msat fees)
|
|
|
|
{
|
2020-04-15 05:08:06 +02:00
|
|
|
send_coin_mvt(take(new_coin_chain_fees(NULL, NULL, txid,
|
2020-04-15 05:40:28 +02:00
|
|
|
blockheight, fees)));
|
2020-04-02 04:35:52 +02:00
|
|
|
}
|
|
|
|
|
2020-04-02 04:16:32 +02:00
|
|
|
static void update_ledger_chain_fees(const struct bitcoin_txid *txid,
|
2020-04-03 23:52:35 +02:00
|
|
|
u32 blockheight,
|
2020-04-02 04:16:32 +02:00
|
|
|
struct amount_sat fees)
|
|
|
|
{
|
|
|
|
struct chain_coin_mvt *mvt;
|
2020-04-15 05:40:28 +02:00
|
|
|
mvt = new_coin_chain_fees_sat(NULL, NULL, txid, blockheight, fees);
|
2020-04-02 04:16:32 +02:00
|
|
|
|
|
|
|
send_coin_mvt(take(mvt));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Log the fees paid on this transaction as 'chain fees'. note that
|
|
|
|
* you *cannot* pass a chaintopology-originated tx to this method,
|
2020-05-27 03:37:44 +02:00
|
|
|
* as they don't have input amounts populated */
|
2020-04-02 04:16:32 +02:00
|
|
|
static struct amount_sat record_chain_fees_tx(const struct bitcoin_txid *txid,
|
2020-04-03 23:52:35 +02:00
|
|
|
const struct bitcoin_tx *tx,
|
|
|
|
u32 blockheight)
|
2020-04-02 04:16:32 +02:00
|
|
|
{
|
|
|
|
struct amount_sat fees;
|
|
|
|
fees = bitcoin_tx_compute_fee(tx);
|
|
|
|
status_debug("recording chain fees for tx %s",
|
|
|
|
type_to_string(tmpctx, struct bitcoin_txid, txid));
|
2020-04-03 23:52:35 +02:00
|
|
|
update_ledger_chain_fees(txid, blockheight, fees);
|
2020-04-02 04:16:32 +02:00
|
|
|
return fees;
|
|
|
|
}
|
|
|
|
|
2020-04-02 04:43:59 +02:00
|
|
|
static void add_amt(struct amount_sat *sum, struct amount_sat amt)
|
|
|
|
{
|
|
|
|
if (!amount_sat_add(sum, *sum, amt))
|
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
|
|
"unable to add %s to %s",
|
|
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
|
|
&amt),
|
|
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
|
|
sum));
|
|
|
|
}
|
|
|
|
|
2020-04-02 04:35:52 +02:00
|
|
|
static void record_mutual_closure(const struct bitcoin_txid *txid,
|
2020-04-03 23:52:35 +02:00
|
|
|
u32 blockheight,
|
2020-04-02 04:35:52 +02:00
|
|
|
struct amount_sat our_out,
|
|
|
|
int output_num)
|
|
|
|
{
|
|
|
|
struct amount_msat chain_fees, output_msat;
|
|
|
|
|
|
|
|
/* First figure out 'fees' we paid on this will include
|
|
|
|
* - 'residue' that can't fit onchain (< 1 sat)
|
|
|
|
* - trimmed output, if our balance is < dust_limit
|
|
|
|
* - fees paid for getting this tx mined
|
|
|
|
*/
|
|
|
|
if (!amount_sat_to_msat(&output_msat, our_out))
|
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
|
|
"unable to convert %s to msat",
|
|
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
|
|
&our_out));
|
|
|
|
|
|
|
|
if (!amount_msat_sub(&chain_fees, our_msat, output_msat))
|
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
|
|
"unable to subtract %s from %s",
|
|
|
|
type_to_string(tmpctx, struct amount_msat,
|
|
|
|
&output_msat),
|
|
|
|
type_to_string(tmpctx, struct amount_msat,
|
|
|
|
&our_msat));
|
|
|
|
|
|
|
|
if (!amount_msat_eq(AMOUNT_MSAT(0), chain_fees))
|
2020-04-03 23:52:35 +02:00
|
|
|
update_ledger_chain_fees_msat(txid, blockheight, chain_fees);
|
2020-04-02 04:35:52 +02:00
|
|
|
|
|
|
|
/* If we have no output, we exit early */
|
|
|
|
if (amount_msat_eq(AMOUNT_MSAT(0), output_msat))
|
|
|
|
return;
|
|
|
|
|
|
|
|
assert(output_num > -1);
|
|
|
|
/* Otherwise, we record the channel withdrawal */
|
2020-04-15 05:08:06 +02:00
|
|
|
send_coin_mvt(take(new_coin_withdrawal(NULL, NULL, txid, txid, output_num,
|
2020-04-15 05:40:28 +02:00
|
|
|
blockheight, output_msat)));
|
2020-04-02 04:35:52 +02:00
|
|
|
}
|
|
|
|
|
2020-04-02 04:43:59 +02:00
|
|
|
static void record_chain_fees_unilateral(const struct bitcoin_txid *txid,
|
2020-04-03 23:52:35 +02:00
|
|
|
u32 blockheight,
|
2020-04-02 04:43:59 +02:00
|
|
|
struct amount_sat funding,
|
|
|
|
struct amount_sat their_outs,
|
|
|
|
struct amount_sat our_outs)
|
|
|
|
{
|
|
|
|
struct amount_msat trimmed;
|
|
|
|
status_debug("chain_movements...recording chain fees for unilateral."
|
|
|
|
" our msat balance %s, funding %s,"
|
|
|
|
" their_outs %s, our outs %s",
|
|
|
|
type_to_string(tmpctx, struct amount_msat, &our_msat),
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &funding),
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &their_outs),
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &our_outs));
|
|
|
|
|
2020-04-09 01:18:00 +02:00
|
|
|
/* It's possible they published a commitment tx that
|
|
|
|
* paid us an htlc before we updated our balance. It's also
|
|
|
|
* possible that they fulfilled an htlc, but we'll just write
|
|
|
|
* that down in the chain fees :/ */
|
|
|
|
if (!amount_msat_greater_eq_sat(our_msat, our_outs)) {
|
|
|
|
struct amount_msat missing;
|
|
|
|
|
|
|
|
if (!amount_sat_sub_msat(&missing, our_outs, our_msat))
|
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
|
|
"unable to subtract %s from %s",
|
|
|
|
type_to_string(tmpctx, struct amount_msat,
|
|
|
|
&our_msat),
|
|
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
|
|
&our_outs));
|
|
|
|
|
|
|
|
/* Log the difference and update our_msat */
|
2020-04-15 05:08:06 +02:00
|
|
|
send_coin_mvt(take(new_coin_journal_entry(NULL, NULL, txid,
|
|
|
|
NULL, 0, blockheight,
|
2020-04-15 05:40:28 +02:00
|
|
|
missing, true)));
|
2020-04-09 01:18:00 +02:00
|
|
|
if (!amount_msat_add(&our_msat, our_msat, missing))
|
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
|
|
"unable to add %s to %s",
|
|
|
|
type_to_string(tmpctx, struct amount_msat,
|
|
|
|
&missing),
|
|
|
|
type_to_string(tmpctx, struct amount_msat,
|
|
|
|
&our_msat));
|
|
|
|
}
|
|
|
|
|
2020-04-02 04:43:59 +02:00
|
|
|
/* we need to figure out what we paid in fees, total.
|
|
|
|
* this encompasses the actual chain fees + any trimmed outputs */
|
|
|
|
if (!amount_msat_sub_sat(&trimmed, our_msat, our_outs))
|
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
|
|
"unable to subtract %s from %s",
|
|
|
|
type_to_string(tmpctx, struct amount_sat,
|
2020-04-09 01:18:00 +02:00
|
|
|
&our_outs),
|
|
|
|
type_to_string(tmpctx, struct amount_msat,
|
|
|
|
&our_msat));
|
2020-04-02 04:43:59 +02:00
|
|
|
|
|
|
|
status_debug("logging 'chain fees' for unilateral (trimmed) %s",
|
|
|
|
type_to_string(tmpctx, struct amount_msat, &trimmed));
|
2020-04-03 23:52:35 +02:00
|
|
|
update_ledger_chain_fees_msat(txid, blockheight, trimmed);
|
2020-04-02 04:43:59 +02:00
|
|
|
}
|
|
|
|
|
2020-04-02 04:41:19 +02:00
|
|
|
static void record_coin_loss(const struct bitcoin_txid *txid,
|
2020-04-03 23:52:35 +02:00
|
|
|
u32 blockheight,
|
2020-04-02 04:41:19 +02:00
|
|
|
struct tracked_output *out)
|
|
|
|
{
|
|
|
|
struct chain_coin_mvt *mvt;
|
|
|
|
/* We don't for sure know that it's a 'penalty'
|
|
|
|
* but we write it as that anyway... */
|
2020-04-15 05:08:06 +02:00
|
|
|
mvt = new_coin_penalty_sat(NULL, NULL, txid, &out->txid,
|
2020-04-15 05:40:28 +02:00
|
|
|
out->outnum, blockheight, out->sat);
|
2020-04-02 04:41:19 +02:00
|
|
|
|
|
|
|
send_coin_mvt(take(mvt));
|
|
|
|
}
|
|
|
|
|
2020-04-02 04:16:32 +02:00
|
|
|
static void record_channel_withdrawal_minus_fees(const struct bitcoin_txid *tx_txid,
|
|
|
|
struct tracked_output *out,
|
2020-04-03 23:52:35 +02:00
|
|
|
u32 blockheight,
|
2020-04-02 04:16:32 +02:00
|
|
|
struct amount_sat fees)
|
|
|
|
{
|
|
|
|
struct amount_sat emitted_amt;
|
|
|
|
|
|
|
|
if (!amount_sat_sub(&emitted_amt, out->sat, fees))
|
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
|
|
"unable to subtract %s from %s",
|
|
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
|
|
&fees),
|
|
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
|
|
&out->sat));
|
|
|
|
|
2020-04-15 05:08:06 +02:00
|
|
|
send_coin_mvt(take(new_coin_withdrawal_sat(
|
|
|
|
NULL, NULL, tx_txid, &out->txid,
|
2020-04-15 05:40:28 +02:00
|
|
|
out->outnum, blockheight, emitted_amt)));
|
2020-04-02 04:16:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-04-02 04:41:19 +02:00
|
|
|
static void record_channel_withdrawal(const struct bitcoin_txid *tx_txid,
|
2020-04-03 23:52:35 +02:00
|
|
|
u32 blockheight,
|
2020-04-02 04:41:19 +02:00
|
|
|
struct tracked_output *out)
|
|
|
|
{
|
2020-04-03 23:52:35 +02:00
|
|
|
record_channel_withdrawal_minus_fees(tx_txid, out, blockheight, AMOUNT_SAT(0));
|
2020-04-02 04:41:19 +02:00
|
|
|
}
|
|
|
|
|
2020-04-02 04:16:32 +02:00
|
|
|
static bool is_our_htlc_tx(struct tracked_output *out)
|
|
|
|
{
|
|
|
|
return out->resolved &&
|
|
|
|
(out->resolved->tx_type == OUR_HTLC_TIMEOUT_TX
|
|
|
|
|| out->resolved->tx_type == OUR_HTLC_SUCCESS_TX);
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool is_channel_deposit(struct tracked_output *out)
|
|
|
|
{
|
|
|
|
return out->resolved &&
|
|
|
|
(out->resolved->tx_type == THEIR_HTLC_FULFILL_TO_US
|
|
|
|
|| out->resolved->tx_type == OUR_HTLC_SUCCESS_TX);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void record_coin_movements(struct tracked_output *out,
|
2020-04-03 23:52:35 +02:00
|
|
|
u32 blockheight,
|
2020-04-02 04:16:32 +02:00
|
|
|
const struct bitcoin_tx *tx,
|
|
|
|
const struct bitcoin_txid *txid)
|
|
|
|
{
|
|
|
|
struct amount_sat fees;
|
|
|
|
/* there is a case where we've fulfilled an htlc onchain,
|
|
|
|
* in which case we log a deposit to the channel */
|
|
|
|
if (is_channel_deposit(out))
|
2020-04-03 23:52:35 +02:00
|
|
|
record_htlc_fulfilled(txid, out, blockheight, true);
|
2020-04-02 04:16:32 +02:00
|
|
|
|
|
|
|
|
|
|
|
/* record fees paid for the tx here */
|
|
|
|
/* FIXME: for now, every resolution generates its own tx,
|
|
|
|
* this will need to be updated if we switch to batching */
|
2020-04-03 23:52:35 +02:00
|
|
|
fees = record_chain_fees_tx(txid, tx, blockheight);
|
2020-04-02 04:16:32 +02:00
|
|
|
|
|
|
|
/* we don't record a channel withdrawal until we get to
|
|
|
|
* the 'exit' utxo, which for local commitment htlc txs
|
|
|
|
* is the child htlc_tx's output */
|
|
|
|
if (!is_our_htlc_tx(out))
|
2020-04-03 23:52:35 +02:00
|
|
|
record_channel_withdrawal_minus_fees(txid, out, blockheight, fees);
|
2020-04-02 04:16:32 +02:00
|
|
|
}
|
|
|
|
|
2018-04-03 06:30:48 +02:00
|
|
|
/* We vary feerate until signature they offered matches. */
|
2019-02-21 04:45:55 +01:00
|
|
|
static bool grind_htlc_tx_fee(struct amount_sat *fee,
|
|
|
|
struct bitcoin_tx *tx,
|
|
|
|
const struct bitcoin_signature *remotesig,
|
|
|
|
const u8 *wscript,
|
|
|
|
u64 weight)
|
2017-09-16 01:37:06 +02:00
|
|
|
{
|
2020-05-27 03:37:44 +02:00
|
|
|
struct amount_sat prev_fee = AMOUNT_SAT(UINT64_MAX), input_amt;
|
|
|
|
input_amt = psbt_input_get_amount(tx->psbt, 0);
|
2017-09-16 01:37:06 +02:00
|
|
|
|
2018-04-03 06:30:48 +02:00
|
|
|
for (u64 i = min_possible_feerate; i <= max_possible_feerate; i++) {
|
2018-04-03 22:20:57 +02:00
|
|
|
/* BOLT #3:
|
|
|
|
*
|
|
|
|
* The fee for an HTLC-timeout transaction:
|
|
|
|
* - MUST BE calculated to match:
|
2020-08-20 08:49:47 +02:00
|
|
|
* 1. Multiply `feerate_per_kw` by 663
|
|
|
|
* (666 if `option_anchor_outputs` applies)
|
|
|
|
* and divide by 1000 (rounding down).
|
2018-04-03 22:20:57 +02:00
|
|
|
*
|
|
|
|
* The fee for an HTLC-success transaction:
|
|
|
|
* - MUST BE calculated to match:
|
2020-08-20 08:49:47 +02:00
|
|
|
* 1. Multiply `feerate_per_kw` by 703
|
|
|
|
* (706 if `option_anchor_outputs` applies)
|
|
|
|
* and divide by 1000 (rounding down).
|
2018-04-03 22:20:57 +02:00
|
|
|
*/
|
2019-02-21 04:45:55 +01:00
|
|
|
struct amount_sat out;
|
2017-09-16 01:37:06 +02:00
|
|
|
|
2019-02-21 04:45:55 +01:00
|
|
|
*fee = amount_tx_fee(i, weight);
|
2017-09-16 01:37:06 +02:00
|
|
|
|
|
|
|
/* Minor optimization: don't check same fee twice */
|
2019-02-21 04:45:55 +01:00
|
|
|
if (amount_sat_eq(*fee, prev_fee))
|
2017-09-16 01:37:06 +02:00
|
|
|
continue;
|
|
|
|
|
2019-02-21 04:45:55 +01:00
|
|
|
prev_fee = *fee;
|
2020-05-27 03:37:44 +02:00
|
|
|
if (!amount_sat_sub(&out, input_amt, *fee))
|
2019-02-21 04:45:55 +01:00
|
|
|
break;
|
|
|
|
|
2019-08-21 05:52:44 +02:00
|
|
|
bitcoin_tx_output_set_amount(tx, 0, out);
|
2020-02-08 21:30:03 +01:00
|
|
|
bitcoin_tx_finalize(tx);
|
2018-04-03 06:30:48 +02:00
|
|
|
if (!check_tx_sig(tx, 0, NULL, wscript,
|
2017-11-15 07:20:39 +01:00
|
|
|
&keyset->other_htlc_key, remotesig))
|
2017-09-16 01:37:06 +02:00
|
|
|
continue;
|
|
|
|
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("grind feerate_per_kw for %"PRIu64" = %"PRIu64,
|
2019-02-21 04:45:55 +01:00
|
|
|
weight, i);
|
|
|
|
return true;
|
2017-09-16 01:37:06 +02:00
|
|
|
}
|
2019-02-21 04:45:55 +01:00
|
|
|
return false;
|
2018-04-03 06:30:48 +02:00
|
|
|
}
|
|
|
|
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
static bool set_htlc_timeout_fee(struct bitcoin_tx *tx,
|
2018-12-03 00:15:06 +01:00
|
|
|
const struct bitcoin_signature *remotesig,
|
2018-04-03 06:30:48 +02:00
|
|
|
const u8 *wscript)
|
|
|
|
{
|
2019-09-26 21:07:20 +02:00
|
|
|
static struct amount_sat amount, fee = AMOUNT_SAT_INIT(UINT64_MAX);
|
|
|
|
struct amount_asset asset = bitcoin_tx_output_get_amount(tx, 0);
|
2020-08-13 19:44:02 +02:00
|
|
|
size_t weight;
|
2018-04-03 06:30:48 +02:00
|
|
|
|
2021-04-06 03:21:18 +02:00
|
|
|
/* BOLT #3:
|
2018-04-03 06:30:48 +02:00
|
|
|
*
|
|
|
|
* The fee for an HTLC-timeout transaction:
|
|
|
|
* - MUST BE calculated to match:
|
2020-08-13 19:44:02 +02:00
|
|
|
* 1. Multiply `feerate_per_kw` by 663 (666 if `option_anchor_outputs`
|
|
|
|
* applies) and divide by 1000 (rounding down).
|
2018-04-03 06:30:48 +02:00
|
|
|
*/
|
2020-08-13 19:44:02 +02:00
|
|
|
if (option_anchor_outputs)
|
|
|
|
weight = 666;
|
|
|
|
else
|
|
|
|
weight = 663;
|
|
|
|
weight = elements_add_overhead(weight, tx->wtx->num_inputs,
|
|
|
|
tx->wtx->num_outputs);
|
|
|
|
|
|
|
|
assert(amount_asset_is_main(&asset));
|
|
|
|
amount = amount_asset_to_sat(&asset);
|
|
|
|
|
2019-08-13 09:16:48 +02:00
|
|
|
if (amount_sat_eq(fee, AMOUNT_SAT(UINT64_MAX))) {
|
|
|
|
struct amount_sat grindfee;
|
2019-07-02 17:21:26 +02:00
|
|
|
if (grind_htlc_tx_fee(&grindfee, tx, remotesig, wscript, weight)) {
|
2019-08-13 09:16:48 +02:00
|
|
|
/* Cache this for next time */
|
|
|
|
fee = grindfee;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2018-04-03 06:30:48 +02:00
|
|
|
|
2019-03-20 16:45:21 +01:00
|
|
|
if (!amount_sat_sub(&amount, amount, fee))
|
2019-02-21 04:45:55 +01:00
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
|
|
"Cannot deduct htlc-timeout fee %s from tx %s",
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &fee),
|
|
|
|
type_to_string(tmpctx, struct bitcoin_tx, tx));
|
2019-03-20 16:45:21 +01:00
|
|
|
|
2019-08-21 05:52:44 +02:00
|
|
|
bitcoin_tx_output_set_amount(tx, 0, amount);
|
2020-02-08 21:30:03 +01:00
|
|
|
bitcoin_tx_finalize(tx);
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
return check_tx_sig(tx, 0, NULL, wscript,
|
|
|
|
&keyset->other_htlc_key, remotesig);
|
2018-04-03 06:30:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void set_htlc_success_fee(struct bitcoin_tx *tx,
|
2018-12-03 00:15:06 +01:00
|
|
|
const struct bitcoin_signature *remotesig,
|
2018-04-03 06:30:48 +02:00
|
|
|
const u8 *wscript)
|
|
|
|
{
|
2019-03-22 22:48:04 +01:00
|
|
|
static struct amount_sat amt, fee = AMOUNT_SAT_INIT(UINT64_MAX);
|
2019-09-26 21:07:20 +02:00
|
|
|
struct amount_asset asset;
|
2020-08-13 19:44:02 +02:00
|
|
|
size_t weight;
|
|
|
|
|
2021-04-06 03:21:18 +02:00
|
|
|
/* BOLT #3:
|
2018-04-03 06:30:48 +02:00
|
|
|
*
|
|
|
|
* The fee for an HTLC-success transaction:
|
2020-08-13 19:44:02 +02:00
|
|
|
* - MUST BE calculated to match:
|
|
|
|
* 1. Multiply `feerate_per_kw` by 703 (706 if `option_anchor_outputs`
|
|
|
|
* applies) and divide by 1000 (rounding down).
|
2018-04-03 06:30:48 +02:00
|
|
|
*/
|
2020-08-13 19:44:02 +02:00
|
|
|
if (option_anchor_outputs)
|
|
|
|
weight = 706;
|
|
|
|
else
|
|
|
|
weight = 703;
|
|
|
|
|
|
|
|
weight = elements_add_overhead(weight, tx->wtx->num_inputs,
|
|
|
|
tx->wtx->num_outputs);
|
2019-02-21 04:45:55 +01:00
|
|
|
if (amount_sat_eq(fee, AMOUNT_SAT(UINT64_MAX))) {
|
2019-07-02 17:21:26 +02:00
|
|
|
if (!grind_htlc_tx_fee(&fee, tx, remotesig, wscript, weight))
|
2019-02-21 04:45:55 +01:00
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
|
|
"htlc_success_fee can't be found "
|
2020-05-21 03:57:00 +02:00
|
|
|
"for tx %s, signature %s, wscript %s",
|
2019-02-21 04:45:55 +01:00
|
|
|
type_to_string(tmpctx, struct bitcoin_tx,
|
|
|
|
tx),
|
|
|
|
type_to_string(tmpctx,
|
|
|
|
struct bitcoin_signature,
|
|
|
|
remotesig),
|
|
|
|
tal_hex(tmpctx, wscript));
|
2018-04-03 06:30:48 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-09-26 21:07:20 +02:00
|
|
|
asset = bitcoin_tx_output_get_amount(tx, 0);
|
|
|
|
assert(amount_asset_is_main(&asset));
|
|
|
|
amt = amount_asset_to_sat(&asset);
|
|
|
|
|
2019-03-22 22:48:04 +01:00
|
|
|
if (!amount_sat_sub(&amt, amt, fee))
|
2019-02-21 04:45:55 +01:00
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
|
|
"Cannot deduct htlc-success fee %s from tx %s",
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &fee),
|
|
|
|
type_to_string(tmpctx, struct bitcoin_tx, tx));
|
2019-08-21 05:52:44 +02:00
|
|
|
bitcoin_tx_output_set_amount(tx, 0, amt);
|
2020-02-08 21:30:03 +01:00
|
|
|
bitcoin_tx_finalize(tx);
|
2019-02-21 04:45:55 +01:00
|
|
|
|
2018-04-03 06:30:48 +02:00
|
|
|
if (check_tx_sig(tx, 0, NULL, wscript,
|
|
|
|
&keyset->other_htlc_key, remotesig))
|
|
|
|
return;
|
|
|
|
|
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
2019-02-21 04:45:55 +01:00
|
|
|
"htlc_success_fee %s failed sigcheck "
|
2018-04-03 06:30:48 +02:00
|
|
|
" for tx %s, signature %s, wscript %s",
|
2019-02-21 04:45:55 +01:00
|
|
|
type_to_string(tmpctx, struct amount_sat, &fee),
|
2018-04-03 06:30:48 +02:00
|
|
|
type_to_string(tmpctx, struct bitcoin_tx, tx),
|
2018-12-03 00:15:06 +01:00
|
|
|
type_to_string(tmpctx, struct bitcoin_signature, remotesig),
|
2018-04-03 06:30:48 +02:00
|
|
|
tal_hex(tmpctx, wscript));
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static const char *tx_type_name(enum tx_type tx_type)
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
for (i = 0; enum_tx_type_names[i].name; i++)
|
|
|
|
if (enum_tx_type_names[i].v == tx_type)
|
|
|
|
return enum_tx_type_names[i].name;
|
|
|
|
return "unknown";
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *output_type_name(enum output_type output_type)
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
for (i = 0; enum_output_type_names[i].name; i++)
|
|
|
|
if (enum_output_type_names[i].v == output_type)
|
|
|
|
return enum_output_type_names[i].name;
|
|
|
|
return "unknown";
|
|
|
|
}
|
|
|
|
|
2018-07-23 04:23:02 +02:00
|
|
|
static u8 *delayed_payment_to_us(const tal_t *ctx,
|
|
|
|
struct bitcoin_tx *tx,
|
|
|
|
const u8 *wscript)
|
|
|
|
{
|
2020-08-25 03:55:38 +02:00
|
|
|
return towire_hsmd_sign_delayed_payment_to_us(ctx, commit_num,
|
2020-05-27 03:37:44 +02:00
|
|
|
tx, wscript);
|
2018-07-23 04:23:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static u8 *remote_htlc_to_us(const tal_t *ctx,
|
|
|
|
struct bitcoin_tx *tx,
|
|
|
|
const u8 *wscript)
|
|
|
|
{
|
2020-08-25 03:55:38 +02:00
|
|
|
return towire_hsmd_sign_remote_htlc_to_us(ctx,
|
2018-07-23 04:23:02 +02:00
|
|
|
remote_per_commitment_point,
|
2020-08-13 19:43:02 +02:00
|
|
|
tx, wscript,
|
2020-08-14 03:30:41 +02:00
|
|
|
option_anchor_outputs);
|
2018-07-23 04:23:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static u8 *penalty_to_us(const tal_t *ctx,
|
|
|
|
struct bitcoin_tx *tx,
|
|
|
|
const u8 *wscript)
|
|
|
|
{
|
2020-08-25 03:55:38 +02:00
|
|
|
return towire_hsmd_sign_penalty_to_us(ctx, remote_per_commitment_secret,
|
2020-05-27 03:37:44 +02:00
|
|
|
tx, wscript);
|
2018-07-23 04:23:02 +02:00
|
|
|
}
|
|
|
|
|
2017-09-20 06:45:41 +02:00
|
|
|
/*
|
|
|
|
* This covers:
|
|
|
|
* 1. to-us output spend (`<local_delayedsig> 0`)
|
2017-11-15 07:20:39 +01:00
|
|
|
* 2. the their-commitment, our HTLC timeout case (`<remotehtlcsig> 0`),
|
|
|
|
* 3. the their-commitment, our HTLC redeem case (`<remotehtlcsig> <payment_preimage>`)
|
2017-09-26 23:02:37 +02:00
|
|
|
* 4. the their-revoked-commitment, to-local (`<revocation_sig> 1`)
|
|
|
|
* 5. the their-revoked-commitment, htlc (`<revocation_sig> <revocationkey>`)
|
2018-03-07 01:06:57 +01:00
|
|
|
*
|
|
|
|
* Overrides *tx_type if it all turns to dust.
|
2017-09-20 06:45:41 +02:00
|
|
|
*/
|
|
|
|
static struct bitcoin_tx *tx_to_us(const tal_t *ctx,
|
2018-07-23 04:23:02 +02:00
|
|
|
u8 *(*hsm_sign_msg)(const tal_t *ctx,
|
|
|
|
struct bitcoin_tx *tx,
|
|
|
|
const u8 *wscript),
|
2017-09-20 06:45:41 +02:00
|
|
|
struct tracked_output *out,
|
|
|
|
u32 to_self_delay,
|
|
|
|
u32 locktime,
|
|
|
|
const void *elem, size_t elemsize,
|
|
|
|
const u8 *wscript,
|
2020-03-10 14:11:47 +01:00
|
|
|
enum tx_type *tx_type,
|
|
|
|
u32 feerate)
|
2017-09-20 06:45:41 +02:00
|
|
|
{
|
|
|
|
struct bitcoin_tx *tx;
|
2019-03-21 14:24:43 +01:00
|
|
|
struct amount_sat fee, min_out, amt;
|
2018-12-03 00:15:06 +01:00
|
|
|
struct bitcoin_signature sig;
|
2019-02-21 04:45:55 +01:00
|
|
|
size_t weight;
|
2018-07-23 04:23:02 +02:00
|
|
|
u8 *msg;
|
2019-03-21 14:24:43 +01:00
|
|
|
u8 **witness;
|
2017-09-20 06:45:41 +02:00
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
tx = bitcoin_tx(ctx, chainparams, 1, 1, locktime);
|
2019-03-21 14:24:43 +01:00
|
|
|
bitcoin_tx_add_input(tx, &out->txid, out->outnum, to_self_delay,
|
2020-05-21 21:46:19 +02:00
|
|
|
NULL, out->sat, NULL, wscript);
|
2017-09-20 06:45:41 +02:00
|
|
|
|
2019-03-21 14:24:43 +01:00
|
|
|
bitcoin_tx_add_output(
|
2020-05-21 03:57:00 +02:00
|
|
|
tx, scriptpubkey_p2wpkh(tx, &our_wallet_pubkey), NULL, out->sat);
|
2017-09-20 06:45:41 +02:00
|
|
|
|
|
|
|
/* Worst-case sig is 73 bytes */
|
2019-07-01 16:02:04 +02:00
|
|
|
weight = bitcoin_tx_weight(tx) + 1 + 3 + 73 + 0 + tal_count(wscript);
|
2019-09-23 19:09:59 +02:00
|
|
|
weight = elements_add_overhead(weight, 1, 1);
|
2020-03-10 14:11:47 +01:00
|
|
|
fee = amount_tx_fee(feerate, weight);
|
2017-09-20 06:45:41 +02:00
|
|
|
|
2018-06-20 08:50:44 +02:00
|
|
|
/* Result is trivial? Spend with small feerate, but don't wait
|
|
|
|
* around for it as it might not confirm. */
|
2019-02-21 04:45:55 +01:00
|
|
|
if (!amount_sat_add(&min_out, dust_limit, fee))
|
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
|
|
"Cannot add dust_limit %s and fee %s",
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &dust_limit),
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &fee));
|
2018-06-20 08:50:44 +02:00
|
|
|
|
2019-02-21 04:45:55 +01:00
|
|
|
if (amount_sat_less(out->sat, min_out)) {
|
|
|
|
/* FIXME: We should use SIGHASH_NONE so others can take it */
|
|
|
|
fee = amount_tx_fee(feerate_floor(), weight);
|
|
|
|
status_unusual("TX %s amount %s too small to"
|
|
|
|
" pay reasonable fee, using minimal fee"
|
|
|
|
" and ignoring",
|
|
|
|
tx_type_name(*tx_type),
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &out->sat));
|
2018-06-20 08:50:44 +02:00
|
|
|
*tx_type = IGNORING_TINY_PAYMENT;
|
|
|
|
}
|
2019-02-21 04:45:55 +01:00
|
|
|
|
|
|
|
/* This can only happen if feerate_floor() is still too high; shouldn't
|
|
|
|
* happen! */
|
2019-03-21 14:24:43 +01:00
|
|
|
if (!amount_sat_sub(&amt, out->sat, fee)) {
|
|
|
|
amt = dust_limit;
|
2019-02-21 04:45:55 +01:00
|
|
|
status_broken("TX %s can't afford minimal feerate"
|
|
|
|
"; setting output to %s",
|
|
|
|
tx_type_name(*tx_type),
|
2019-02-21 04:45:55 +01:00
|
|
|
type_to_string(tmpctx, struct amount_sat,
|
2019-03-22 22:48:04 +01:00
|
|
|
&amt));
|
2019-02-21 04:45:55 +01:00
|
|
|
}
|
2019-08-21 05:52:44 +02:00
|
|
|
bitcoin_tx_output_set_amount(tx, 0, amt);
|
2020-02-08 21:30:03 +01:00
|
|
|
bitcoin_tx_finalize(tx);
|
2017-09-20 06:45:41 +02:00
|
|
|
|
2018-07-23 04:23:02 +02:00
|
|
|
if (!wire_sync_write(HSM_FD, take(hsm_sign_msg(NULL, tx, wscript))))
|
|
|
|
status_failed(STATUS_FAIL_HSM_IO, "Writing sign request to hsm");
|
|
|
|
msg = wire_sync_read(tmpctx, HSM_FD);
|
2020-08-25 03:55:38 +02:00
|
|
|
if (!msg || !fromwire_hsmd_sign_tx_reply(msg, &sig)) {
|
2018-07-23 04:23:02 +02:00
|
|
|
status_failed(STATUS_FAIL_HSM_IO,
|
|
|
|
"Reading sign_tx_reply: %s",
|
|
|
|
tal_hex(tmpctx, msg));
|
|
|
|
}
|
|
|
|
|
2019-03-22 22:48:04 +01:00
|
|
|
witness = bitcoin_witness_sig_and_element(tx, &sig, elem,
|
2019-03-21 14:24:43 +01:00
|
|
|
elemsize, wscript);
|
2019-08-21 05:52:42 +02:00
|
|
|
bitcoin_tx_input_set_witness(tx, 0, take(witness));
|
2017-09-20 06:45:41 +02:00
|
|
|
return tx;
|
|
|
|
}
|
|
|
|
|
2020-09-08 05:22:41 +02:00
|
|
|
/** replace_penalty_tx_to_us
|
|
|
|
*
|
|
|
|
* @brief creates a replacement TX for
|
|
|
|
* a given penalty tx.
|
|
|
|
*
|
|
|
|
* @param ctx - the context to allocate
|
|
|
|
* off of.
|
|
|
|
* @param hsm_sign_msg - function to construct
|
|
|
|
* the signing message to HSM.
|
|
|
|
* @param penalty_tx - the original
|
|
|
|
* penalty transaction.
|
|
|
|
* @param output_amount - the output
|
|
|
|
* amount to use instead of the
|
|
|
|
* original penalty transaction.
|
|
|
|
* If this amount is below the dust
|
|
|
|
* limit, the output is replaced with
|
|
|
|
* an `OP_RETURN` instead.
|
|
|
|
*
|
|
|
|
* @return the signed transaction.
|
|
|
|
*/
|
|
|
|
static struct bitcoin_tx *
|
|
|
|
replace_penalty_tx_to_us(const tal_t *ctx,
|
|
|
|
u8 *(*hsm_sign_msg)(const tal_t *ctx,
|
|
|
|
struct bitcoin_tx *tx,
|
|
|
|
const u8 *wscript),
|
|
|
|
const struct bitcoin_tx *penalty_tx,
|
|
|
|
struct amount_sat output_amount)
|
|
|
|
{
|
|
|
|
struct bitcoin_tx *tx;
|
|
|
|
|
|
|
|
/* The penalty tx input. */
|
|
|
|
const struct wally_tx_input *input;
|
|
|
|
/* Specs of the penalty tx input. */
|
|
|
|
struct bitcoin_txid input_txid;
|
|
|
|
u32 input_outnum;
|
|
|
|
u8 *input_wscript;
|
|
|
|
u8 *input_element;
|
|
|
|
struct amount_sat input_amount;
|
|
|
|
|
|
|
|
/* Signature from the HSM. */
|
|
|
|
u8 *msg;
|
|
|
|
struct bitcoin_signature sig;
|
|
|
|
/* Witness we generate from the signature and other data. */
|
|
|
|
u8 **witness;
|
|
|
|
|
|
|
|
|
|
|
|
/* Get the single input of the penalty tx. */
|
|
|
|
input = &penalty_tx->wtx->inputs[0];
|
|
|
|
/* Extract the input-side data. */
|
|
|
|
bitcoin_tx_input_get_txid(penalty_tx, 0, &input_txid);
|
|
|
|
input_outnum = input->index;
|
|
|
|
input_wscript = tal_dup_arr(tmpctx, u8,
|
|
|
|
input->witness->items[2].witness,
|
|
|
|
input->witness->items[2].witness_len,
|
|
|
|
0);
|
|
|
|
input_element = tal_dup_arr(tmpctx, u8,
|
|
|
|
input->witness->items[1].witness,
|
|
|
|
input->witness->items[1].witness_len,
|
|
|
|
0);
|
|
|
|
input_amount = psbt_input_get_amount(penalty_tx->psbt, 0);
|
|
|
|
|
|
|
|
/* Create the replacement. */
|
|
|
|
tx = bitcoin_tx(ctx, chainparams, 1, 1, /*locktime*/ 0);
|
|
|
|
/* Reconstruct the input. */
|
|
|
|
bitcoin_tx_add_input(tx, &input_txid, input_outnum,
|
|
|
|
BITCOIN_TX_RBF_SEQUENCE,
|
|
|
|
NULL, input_amount, NULL, input_wscript);
|
|
|
|
/* Reconstruct the output with a smaller amount. */
|
|
|
|
if (amount_sat_greater(output_amount, dust_limit))
|
|
|
|
bitcoin_tx_add_output(tx,
|
|
|
|
scriptpubkey_p2wpkh(tx,
|
|
|
|
&our_wallet_pubkey),
|
|
|
|
NULL,
|
|
|
|
output_amount);
|
|
|
|
else
|
|
|
|
bitcoin_tx_add_output(tx,
|
|
|
|
scriptpubkey_opreturn_padded(tx),
|
|
|
|
NULL,
|
|
|
|
AMOUNT_SAT(0));
|
|
|
|
|
|
|
|
/* Finalize the transaction. */
|
|
|
|
bitcoin_tx_finalize(tx);
|
|
|
|
|
|
|
|
/* Ask HSM to sign it. */
|
|
|
|
if (!wire_sync_write(HSM_FD, take(hsm_sign_msg(NULL, tx,
|
|
|
|
input_wscript))))
|
|
|
|
status_failed(STATUS_FAIL_HSM_IO, "While feebumping penalty: writing sign request to hsm");
|
|
|
|
msg = wire_sync_read(tmpctx, HSM_FD);
|
|
|
|
if (!msg || !fromwire_hsmd_sign_tx_reply(msg, &sig))
|
|
|
|
status_failed(STATUS_FAIL_HSM_IO, "While feebumping penalty: reading sign_tx_reply: %s", tal_hex(tmpctx, msg));
|
|
|
|
|
|
|
|
/* Install the witness with the signature. */
|
|
|
|
witness = bitcoin_witness_sig_and_element(tx, &sig,
|
|
|
|
input_element,
|
|
|
|
tal_bytelen(input_element),
|
|
|
|
input_wscript);
|
|
|
|
bitcoin_tx_input_set_witness(tx, 0, take(witness));
|
|
|
|
|
|
|
|
return tx;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** min_rbf_bump
|
|
|
|
*
|
|
|
|
* @brief computes the minimum RBF bump required by
|
|
|
|
* BIP125, given an index.
|
|
|
|
*
|
|
|
|
* @desc BIP125 requires that an replacement transaction
|
|
|
|
* pay, not just the fee of the evicted transactions,
|
|
|
|
* but also the minimum relay fee for itself.
|
|
|
|
* This function assumes that previous RBF attempts
|
|
|
|
* paid exactly the return value for that attempt, on
|
|
|
|
* top of the initial transaction fee.
|
|
|
|
* It can serve as a baseline for other functions that
|
|
|
|
* compute a suggested fee: get whichever is higher,
|
|
|
|
* the fee this function suggests, or your own unique
|
|
|
|
* function.
|
|
|
|
*
|
|
|
|
* This function is provided as a common function that
|
|
|
|
* all RBF-bump computations can use.
|
|
|
|
*
|
|
|
|
* @param weight - the weight of the transaction you
|
|
|
|
* are RBFing.
|
|
|
|
* @param index - 0 makes no sense, 1 means this is
|
|
|
|
* the first RBF attempt, 2 means this is the 2nd
|
|
|
|
* RBF attempt, etc.
|
|
|
|
*
|
|
|
|
* @return the suggested total fee.
|
|
|
|
*/
|
|
|
|
static struct amount_sat min_rbf_bump(size_t weight,
|
|
|
|
size_t index)
|
|
|
|
{
|
|
|
|
struct amount_sat min_relay_fee;
|
|
|
|
struct amount_sat min_rbf_bump;
|
|
|
|
|
|
|
|
/* Compute the minimum relay fee for a transaction of the given
|
|
|
|
* weight. */
|
|
|
|
min_relay_fee = amount_tx_fee(min_relay_feerate, weight);
|
|
|
|
|
|
|
|
/* For every RBF attempt, we add the min-relay-fee.
|
|
|
|
* Or in other words, we multiply the min-relay-fee by the
|
|
|
|
* index number of the attempt.
|
|
|
|
*/
|
|
|
|
if (mul_overflows_u64(index, min_relay_fee.satoshis)) /* Raw: multiplication. */
|
|
|
|
min_rbf_bump = AMOUNT_SAT(UINT64_MAX);
|
|
|
|
else
|
|
|
|
min_rbf_bump.satoshis = index * min_relay_fee.satoshis; /* Raw: multiplication. */
|
|
|
|
|
|
|
|
return min_rbf_bump;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** compute_penalty_output_amount
|
|
|
|
*
|
|
|
|
* @brief computes the appropriate output amount for a
|
|
|
|
* penalty transaction that spends a theft transaction
|
|
|
|
* that is already of a specific depth.
|
|
|
|
*
|
|
|
|
* @param initial_amount - the outout amount of the first
|
|
|
|
* penalty transaction.
|
|
|
|
* @param depth - the current depth of the theft
|
|
|
|
* transaction.
|
|
|
|
* @param max_depth - the maximum depth of the theft
|
|
|
|
* transaction, after which the theft transaction will
|
|
|
|
* succeed.
|
|
|
|
* @param weight - the weight of the first penalty
|
|
|
|
* transaction, in Sipa.
|
|
|
|
*/
|
|
|
|
static struct amount_sat
|
|
|
|
compute_penalty_output_amount(struct amount_sat initial_amount,
|
|
|
|
u32 depth, u32 max_depth,
|
|
|
|
size_t weight)
|
|
|
|
{
|
|
|
|
struct amount_sat max_output_amount;
|
|
|
|
struct amount_sat output_amount;
|
|
|
|
struct amount_sat deducted_amount;
|
|
|
|
|
|
|
|
assert(depth <= max_depth);
|
|
|
|
assert(depth > 0);
|
|
|
|
|
|
|
|
/* The difference between initial_amount, and the fee suggested
|
|
|
|
* by min_rbf_bump, is the largest allowed output amount.
|
|
|
|
*
|
|
|
|
* depth = 1 is the first attempt, thus maps to the 0th RBF
|
|
|
|
* (i.e. the initial attempt that is not RBFed itself).
|
|
|
|
* We actually start to replace at depth = 2, so we use
|
|
|
|
* depth - 1 as the index for min_rbf_bump.
|
|
|
|
*/
|
|
|
|
if (!amount_sat_sub(&max_output_amount,
|
|
|
|
initial_amount, min_rbf_bump(weight, depth - 1)))
|
|
|
|
/* If min_rbf_bump is larger than the initial_amount,
|
|
|
|
* we should just donate the whole output as fee,
|
|
|
|
* meaning we get 0 output amount.
|
|
|
|
*/
|
|
|
|
return AMOUNT_SAT(0);
|
|
|
|
|
|
|
|
/* Map the depth / max_depth into a number between 0->1. */
|
|
|
|
double x = (double) depth / (double) max_depth;
|
|
|
|
/* Get the cube of the above position, resulting in a graph
|
|
|
|
* where the y is close to 0 up to less than halfway through,
|
|
|
|
* then quickly rises up to 1 as depth nears the max depth.
|
|
|
|
*/
|
|
|
|
double y = x * x * x;
|
|
|
|
/* Scale according to the initial_amount. */
|
|
|
|
deducted_amount.satoshis = (u64) (y * initial_amount.satoshis); /* Raw: multiplication. */
|
|
|
|
|
|
|
|
/* output_amount = initial_amount - deducted_amount. */
|
|
|
|
if (!amount_sat_sub(&output_amount,
|
|
|
|
initial_amount, deducted_amount))
|
|
|
|
/* If underflow, force to 0. */
|
|
|
|
output_amount = AMOUNT_SAT(0);
|
|
|
|
|
|
|
|
/* If output exceeds max, return max. */
|
|
|
|
if (amount_sat_less(max_output_amount, output_amount))
|
|
|
|
return max_output_amount;
|
|
|
|
|
|
|
|
return output_amount;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-07-23 04:23:02 +02:00
|
|
|
static void hsm_sign_local_htlc_tx(struct bitcoin_tx *tx,
|
|
|
|
const u8 *wscript,
|
2018-12-03 00:15:06 +01:00
|
|
|
struct bitcoin_signature *sig)
|
2018-07-23 04:23:02 +02:00
|
|
|
{
|
2020-08-25 03:55:38 +02:00
|
|
|
u8 *msg = towire_hsmd_sign_local_htlc_tx(NULL, commit_num,
|
2020-08-13 19:43:02 +02:00
|
|
|
tx, wscript,
|
2020-08-14 03:30:41 +02:00
|
|
|
option_anchor_outputs);
|
2018-07-23 04:23:02 +02:00
|
|
|
|
|
|
|
if (!wire_sync_write(HSM_FD, take(msg)))
|
|
|
|
status_failed(STATUS_FAIL_HSM_IO,
|
|
|
|
"Writing sign_local_htlc_tx to hsm");
|
|
|
|
msg = wire_sync_read(tmpctx, HSM_FD);
|
2020-08-25 03:55:38 +02:00
|
|
|
if (!msg || !fromwire_hsmd_sign_tx_reply(msg, sig))
|
2018-07-23 04:23:02 +02:00
|
|
|
status_failed(STATUS_FAIL_HSM_IO,
|
|
|
|
"Reading sign_local_htlc_tx: %s",
|
|
|
|
tal_hex(tmpctx, msg));
|
|
|
|
}
|
|
|
|
|
2018-07-23 04:23:03 +02:00
|
|
|
static void hsm_get_per_commitment_point(struct pubkey *per_commitment_point)
|
|
|
|
{
|
2020-08-25 03:55:38 +02:00
|
|
|
u8 *msg = towire_hsmd_get_per_commitment_point(NULL, commit_num);
|
2018-07-23 04:23:03 +02:00
|
|
|
struct secret *unused;
|
|
|
|
|
|
|
|
if (!wire_sync_write(HSM_FD, take(msg)))
|
|
|
|
status_failed(STATUS_FAIL_HSM_IO, "Writing sign_htlc_tx to hsm");
|
|
|
|
msg = wire_sync_read(tmpctx, HSM_FD);
|
|
|
|
if (!msg
|
2020-08-25 03:55:38 +02:00
|
|
|
|| !fromwire_hsmd_get_per_commitment_point_reply(tmpctx, msg,
|
2018-07-23 04:23:03 +02:00
|
|
|
per_commitment_point,
|
|
|
|
&unused))
|
|
|
|
status_failed(STATUS_FAIL_HSM_IO,
|
|
|
|
"Reading hsm_get_per_commitment_point_reply: %s",
|
|
|
|
tal_hex(tmpctx, msg));
|
|
|
|
}
|
|
|
|
|
2017-08-23 03:52:17 +02:00
|
|
|
static struct tracked_output *
|
2020-05-26 05:39:40 +02:00
|
|
|
new_tracked_output(struct tracked_output ***outs,
|
2019-07-30 16:14:43 +02:00
|
|
|
const struct bitcoin_txid *txid,
|
|
|
|
u32 tx_blockheight,
|
|
|
|
enum tx_type tx_type,
|
|
|
|
u32 outnum,
|
|
|
|
struct amount_sat sat,
|
|
|
|
enum output_type output_type,
|
|
|
|
const struct htlc_stub *htlc,
|
|
|
|
const u8 *wscript,
|
2020-08-13 19:45:02 +02:00
|
|
|
const struct bitcoin_signature *remote_htlc_sig TAKES)
|
2017-08-23 03:52:17 +02:00
|
|
|
{
|
|
|
|
struct tracked_output *out = tal(*outs, struct tracked_output);
|
|
|
|
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("Tracking output %u of %s: %s/%s",
|
2017-08-23 03:52:17 +02:00
|
|
|
outnum,
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct bitcoin_txid, txid),
|
2017-08-23 03:52:17 +02:00
|
|
|
tx_type_name(tx_type),
|
|
|
|
output_type_name(output_type));
|
|
|
|
|
|
|
|
out->tx_type = tx_type;
|
|
|
|
out->txid = *txid;
|
|
|
|
out->tx_blockheight = tx_blockheight;
|
2018-02-23 06:53:47 +01:00
|
|
|
out->depth = 0;
|
2017-08-23 03:52:17 +02:00
|
|
|
out->outnum = outnum;
|
2019-02-21 04:45:55 +01:00
|
|
|
out->sat = sat;
|
2017-08-23 03:52:17 +02:00
|
|
|
out->output_type = output_type;
|
|
|
|
out->proposal = NULL;
|
|
|
|
out->resolved = NULL;
|
2018-11-22 03:17:29 +01:00
|
|
|
if (htlc)
|
|
|
|
out->htlc = *htlc;
|
|
|
|
out->wscript = tal_steal(out, wscript);
|
2020-08-13 19:45:02 +02:00
|
|
|
if (remote_htlc_sig)
|
|
|
|
out->remote_htlc_sig = tal_dup(out, struct bitcoin_signature,
|
|
|
|
remote_htlc_sig);
|
|
|
|
else
|
2018-12-03 00:15:06 +01:00
|
|
|
out->remote_htlc_sig = NULL;
|
2017-08-23 03:52:17 +02:00
|
|
|
|
2019-01-15 04:51:27 +01:00
|
|
|
tal_arr_expand(outs, out);
|
2017-08-23 03:52:17 +02:00
|
|
|
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ignore_output(struct tracked_output *out)
|
|
|
|
{
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("Ignoring output %u of %s: %s/%s",
|
2017-08-23 03:52:17 +02:00
|
|
|
out->outnum,
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct bitcoin_txid, &out->txid),
|
2017-08-23 03:52:17 +02:00
|
|
|
tx_type_name(out->tx_type),
|
|
|
|
output_type_name(out->output_type));
|
|
|
|
|
|
|
|
out->resolved = tal(out, struct resolution);
|
|
|
|
out->resolved->txid = out->txid;
|
|
|
|
out->resolved->depth = 0;
|
|
|
|
out->resolved->tx_type = SELF;
|
|
|
|
}
|
|
|
|
|
2019-06-07 11:38:20 +02:00
|
|
|
static enum wallet_tx_type onchain_txtype_to_wallet_txtype(enum tx_type t)
|
2019-05-27 13:04:10 +02:00
|
|
|
{
|
|
|
|
switch (t) {
|
|
|
|
case FUNDING_TRANSACTION:
|
|
|
|
return TX_CHANNEL_FUNDING;
|
|
|
|
case MUTUAL_CLOSE:
|
|
|
|
return TX_CHANNEL_CLOSE;
|
|
|
|
case OUR_UNILATERAL:
|
|
|
|
return TX_CHANNEL_UNILATERAL;
|
|
|
|
case THEIR_HTLC_FULFILL_TO_US:
|
|
|
|
case OUR_HTLC_SUCCESS_TX:
|
|
|
|
return TX_CHANNEL_HTLC_SUCCESS;
|
|
|
|
case OUR_HTLC_TIMEOUT_TO_US:
|
|
|
|
case OUR_HTLC_TIMEOUT_TX:
|
|
|
|
return TX_CHANNEL_HTLC_TIMEOUT;
|
|
|
|
case OUR_DELAYED_RETURN_TO_WALLET:
|
|
|
|
case SELF:
|
|
|
|
return TX_CHANNEL_SWEEP;
|
|
|
|
case OUR_PENALTY_TX:
|
|
|
|
return TX_CHANNEL_PENALTY;
|
2020-04-02 04:48:39 +02:00
|
|
|
case THEIR_DELAYED_CHEAT:
|
|
|
|
return TX_CHANNEL_CHEAT | TX_THEIRS;
|
2019-05-27 13:04:10 +02:00
|
|
|
case THEIR_UNILATERAL:
|
|
|
|
case UNKNOWN_UNILATERAL:
|
|
|
|
case THEIR_REVOKED_UNILATERAL:
|
|
|
|
return TX_CHANNEL_UNILATERAL | TX_THEIRS;
|
|
|
|
case THEIR_HTLC_TIMEOUT_TO_THEM:
|
|
|
|
return TX_CHANNEL_HTLC_TIMEOUT | TX_THEIRS;
|
|
|
|
case OUR_HTLC_FULFILL_TO_THEM:
|
|
|
|
return TX_CHANNEL_HTLC_SUCCESS | TX_THEIRS;
|
|
|
|
case IGNORING_TINY_PAYMENT:
|
|
|
|
case UNKNOWN_TXTYPE:
|
|
|
|
return TX_UNKNOWN;
|
|
|
|
}
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
2020-09-08 05:22:41 +02:00
|
|
|
/** proposal_is_rbfable
|
|
|
|
*
|
|
|
|
* @brief returns true if the given proposal
|
|
|
|
* would be RBFed if the output it is tracking
|
|
|
|
* increases in depth without being spent.
|
|
|
|
*/
|
|
|
|
static bool proposal_is_rbfable(const struct proposed_resolution *proposal)
|
|
|
|
{
|
|
|
|
/* Future onchain resolutions, such as anchored commitments, might
|
|
|
|
* want to RBF as well.
|
|
|
|
*/
|
|
|
|
return proposal->tx_type == OUR_PENALTY_TX;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** proposal_should_rbf
|
|
|
|
*
|
|
|
|
* @brief the given output just increased its depth,
|
|
|
|
* so the proposal for it should be RBFed and
|
|
|
|
* rebroadcast.
|
|
|
|
*
|
|
|
|
* @desc precondition: the given output must have an
|
|
|
|
* rbfable proposal as per `proposal_is_rbfable`.
|
|
|
|
*/
|
|
|
|
static void proposal_should_rbf(struct tracked_output *out, bool is_replay)
|
|
|
|
{
|
|
|
|
struct bitcoin_tx *tx = NULL;
|
|
|
|
u32 depth;
|
|
|
|
|
|
|
|
assert(out->proposal);
|
|
|
|
assert(proposal_is_rbfable(out->proposal));
|
|
|
|
|
|
|
|
depth = out->depth;
|
|
|
|
|
|
|
|
/* Do not RBF at depth 1.
|
|
|
|
*
|
|
|
|
* Since we react to *onchain* events, whatever proposal we made,
|
|
|
|
* the output for that proposal is already at depth 1.
|
|
|
|
*
|
|
|
|
* Since our initial proposal was broadcasted with the output at
|
|
|
|
* depth 1, we should not RBF until a new block arrives, which is
|
|
|
|
* at depth 2.
|
|
|
|
*/
|
|
|
|
if (depth <= 1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (out->proposal->tx_type == OUR_PENALTY_TX) {
|
|
|
|
u32 max_depth = to_self_delay[REMOTE];
|
|
|
|
u32 my_depth = depth;
|
|
|
|
size_t weight = bitcoin_tx_weight(out->proposal->tx);
|
|
|
|
struct amount_sat initial_amount;
|
|
|
|
struct amount_sat new_amount;
|
|
|
|
|
|
|
|
if (max_depth >= 1)
|
|
|
|
max_depth -= 1;
|
|
|
|
if (my_depth >= max_depth)
|
|
|
|
my_depth = max_depth;
|
|
|
|
|
|
|
|
bitcoin_tx_output_get_amount_sat(out->proposal->tx, 0,
|
|
|
|
&initial_amount);
|
|
|
|
|
|
|
|
/* Compute the new output amount for the RBF. */
|
|
|
|
new_amount = compute_penalty_output_amount(initial_amount,
|
|
|
|
my_depth, max_depth,
|
|
|
|
weight);
|
|
|
|
assert(amount_sat_less_eq(new_amount, initial_amount));
|
|
|
|
/* Recreate the penalty tx. */
|
|
|
|
tx = replace_penalty_tx_to_us(tmpctx,
|
|
|
|
&penalty_to_us,
|
|
|
|
out->proposal->tx, new_amount);
|
|
|
|
|
|
|
|
status_debug("Created RBF OUR_PENALTY_TX with output %s "
|
|
|
|
"(originally %s) for depth %"PRIu32"/%"PRIu32".",
|
|
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
|
|
&new_amount),
|
|
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
|
|
&initial_amount),
|
|
|
|
depth, to_self_delay[LOCAL]);
|
|
|
|
}
|
|
|
|
/* Add other RBF-able proposals here. */
|
|
|
|
|
|
|
|
/* Broadcast the transaction. */
|
|
|
|
if (tx) {
|
|
|
|
enum wallet_tx_type wtt;
|
|
|
|
|
|
|
|
status_debug("Broadcasting RBF %s (%s) to resolve %s/%s "
|
|
|
|
"depth=%"PRIu32"",
|
|
|
|
tx_type_name(out->proposal->tx_type),
|
|
|
|
type_to_string(tmpctx, struct bitcoin_tx, tx),
|
|
|
|
tx_type_name(out->tx_type),
|
|
|
|
output_type_name(out->output_type),
|
|
|
|
depth);
|
|
|
|
|
|
|
|
wtt = onchain_txtype_to_wallet_txtype(out->proposal->tx_type);
|
|
|
|
wire_sync_write(REQ_FD,
|
|
|
|
take(towire_onchaind_broadcast_tx(NULL, tx,
|
|
|
|
wtt,
|
|
|
|
true)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-03 03:46:18 +02:00
|
|
|
static void proposal_meets_depth(struct tracked_output *out, bool is_replay)
|
2017-09-26 06:57:31 +02:00
|
|
|
{
|
2020-09-08 05:22:41 +02:00
|
|
|
bool is_rbf = false;
|
|
|
|
|
2017-09-26 06:57:31 +02:00
|
|
|
/* If we simply wanted to ignore it after some depth */
|
|
|
|
if (!out->proposal->tx) {
|
|
|
|
ignore_output(out);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("Broadcasting %s (%s) to resolve %s/%s",
|
2017-09-26 06:57:31 +02:00
|
|
|
tx_type_name(out->proposal->tx_type),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct bitcoin_tx, out->proposal->tx),
|
2017-09-26 06:57:31 +02:00
|
|
|
tx_type_name(out->tx_type),
|
|
|
|
output_type_name(out->output_type));
|
|
|
|
|
2020-09-08 05:22:41 +02:00
|
|
|
if (out->proposal)
|
|
|
|
/* Our own penalty transactions are going to be RBFed. */
|
|
|
|
is_rbf = proposal_is_rbfable(out->proposal);
|
|
|
|
|
2019-05-27 13:04:10 +02:00
|
|
|
wire_sync_write(
|
|
|
|
REQ_FD,
|
2020-08-25 04:15:48 +02:00
|
|
|
take(towire_onchaind_broadcast_tx(
|
2020-04-03 23:52:35 +02:00
|
|
|
NULL, out->proposal->tx,
|
2020-09-08 05:21:02 +02:00
|
|
|
onchain_txtype_to_wallet_txtype(out->proposal->tx_type),
|
2020-09-08 05:22:41 +02:00
|
|
|
is_rbf)));
|
2018-06-20 08:50:44 +02:00
|
|
|
|
|
|
|
/* Don't wait for this if we're ignoring the tiny payment. */
|
2020-04-02 04:45:21 +02:00
|
|
|
if (out->proposal->tx_type == IGNORING_TINY_PAYMENT) {
|
|
|
|
struct bitcoin_txid txid;
|
|
|
|
struct amount_sat fees;
|
|
|
|
|
2018-06-20 08:50:44 +02:00
|
|
|
ignore_output(out);
|
2020-04-03 03:46:18 +02:00
|
|
|
|
|
|
|
if (!is_replay) {
|
|
|
|
/* log the coin movements here, since we're not
|
|
|
|
* going to wait til we hear about it */
|
|
|
|
bitcoin_txid(out->proposal->tx, &txid);
|
2020-04-03 23:52:35 +02:00
|
|
|
fees = record_chain_fees_tx(&txid, out->proposal->tx, 0);
|
|
|
|
record_channel_withdrawal_minus_fees(&txid, out, 0, fees);
|
2020-04-03 03:46:18 +02:00
|
|
|
}
|
2020-04-02 04:45:21 +02:00
|
|
|
}
|
2018-06-20 08:50:44 +02:00
|
|
|
|
2019-07-05 07:28:20 +02:00
|
|
|
/* Otherwise we will get a callback when it's in a block. */
|
2017-09-26 06:57:31 +02:00
|
|
|
}
|
|
|
|
|
2017-08-23 03:52:17 +02:00
|
|
|
static void propose_resolution(struct tracked_output *out,
|
|
|
|
const struct bitcoin_tx *tx,
|
|
|
|
unsigned int depth_required,
|
2020-04-03 03:46:18 +02:00
|
|
|
enum tx_type tx_type,
|
|
|
|
bool is_replay)
|
2017-08-23 03:52:17 +02:00
|
|
|
{
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("Propose handling %s/%s by %s (%s) after %u blocks",
|
2017-08-23 03:52:17 +02:00
|
|
|
tx_type_name(out->tx_type),
|
|
|
|
output_type_name(out->output_type),
|
|
|
|
tx_type_name(tx_type),
|
2018-03-15 05:30:38 +01:00
|
|
|
tx ? type_to_string(tmpctx, struct bitcoin_tx, tx):"IGNORING",
|
2017-08-23 03:52:17 +02:00
|
|
|
depth_required);
|
|
|
|
|
|
|
|
out->proposal = tal(out, struct proposed_resolution);
|
|
|
|
out->proposal->tx = tal_steal(out->proposal, tx);
|
|
|
|
out->proposal->depth_required = depth_required;
|
|
|
|
out->proposal->tx_type = tx_type;
|
2017-09-26 06:57:31 +02:00
|
|
|
|
|
|
|
if (depth_required == 0)
|
2020-04-03 03:46:18 +02:00
|
|
|
proposal_meets_depth(out, is_replay);
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void propose_resolution_at_block(struct tracked_output *out,
|
|
|
|
const struct bitcoin_tx *tx,
|
|
|
|
unsigned int block_required,
|
2020-04-03 03:46:18 +02:00
|
|
|
enum tx_type tx_type,
|
|
|
|
bool is_replay)
|
2017-08-23 03:52:17 +02:00
|
|
|
{
|
|
|
|
u32 depth;
|
|
|
|
|
|
|
|
/* Expiry could be in the past! */
|
|
|
|
if (block_required < out->tx_blockheight)
|
|
|
|
depth = 0;
|
2018-03-07 01:06:57 +01:00
|
|
|
else /* Note that out->tx_blockheight is already at depth 1 */
|
|
|
|
depth = block_required - out->tx_blockheight + 1;
|
2020-04-03 03:46:18 +02:00
|
|
|
propose_resolution(out, tx, depth, tx_type, is_replay);
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
|
2018-03-07 01:06:56 +01:00
|
|
|
static bool is_valid_sig(const u8 *e)
|
|
|
|
{
|
2018-12-03 00:15:06 +01:00
|
|
|
struct bitcoin_signature sig;
|
|
|
|
return signature_from_der(e, tal_count(e), &sig);
|
2018-03-07 01:06:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* We ignore things which look like signatures. */
|
2019-03-22 22:48:04 +01:00
|
|
|
static bool input_similar(const struct wally_tx_input *i1,
|
|
|
|
const struct wally_tx_input *i2)
|
2018-03-07 01:06:56 +01:00
|
|
|
{
|
2019-03-22 22:48:04 +01:00
|
|
|
u8 *s1, *s2;
|
|
|
|
|
|
|
|
if (!memeq(i1->txhash, WALLY_TXHASH_LEN, i2->txhash, WALLY_TXHASH_LEN))
|
2018-03-07 01:06:56 +01:00
|
|
|
return false;
|
|
|
|
|
|
|
|
if (i1->index != i2->index)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (!scripteq(i1->script, i2->script))
|
|
|
|
return false;
|
|
|
|
|
2019-03-22 22:48:04 +01:00
|
|
|
if (i1->sequence != i2->sequence)
|
2018-03-07 01:06:56 +01:00
|
|
|
return false;
|
|
|
|
|
2019-03-22 22:48:04 +01:00
|
|
|
if (i1->witness->num_items != i2->witness->num_items)
|
2018-03-07 01:06:56 +01:00
|
|
|
return false;
|
|
|
|
|
2019-03-22 22:48:04 +01:00
|
|
|
for (size_t i = 0; i < i1->witness->num_items; i++) {
|
|
|
|
/* Need to wrap these in `tal_arr`s since the primitives
|
|
|
|
* except to be able to call tal_bytelen on them */
|
|
|
|
s1 = tal_dup_arr(tmpctx, u8, i1->witness->items[i].witness,
|
|
|
|
i1->witness->items[i].witness_len, 0);
|
|
|
|
s2 = tal_dup_arr(tmpctx, u8, i2->witness->items[i].witness,
|
|
|
|
i2->witness->items[i].witness_len, 0);
|
|
|
|
|
|
|
|
if (scripteq(s1, s2))
|
2018-03-07 01:06:56 +01:00
|
|
|
continue;
|
|
|
|
|
2019-03-22 22:48:04 +01:00
|
|
|
if (is_valid_sig(s1) && is_valid_sig(s2))
|
2018-03-07 01:06:56 +01:00
|
|
|
continue;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-08-23 03:52:17 +02:00
|
|
|
/* This simple case: true if this was resolved by our proposal. */
|
|
|
|
static bool resolved_by_proposal(struct tracked_output *out,
|
2020-05-26 05:39:40 +02:00
|
|
|
const struct tx_parts *tx_parts)
|
2017-08-23 03:52:17 +02:00
|
|
|
{
|
|
|
|
/* If there's no TX associated, it's not us. */
|
|
|
|
if (!out->proposal->tx)
|
|
|
|
return false;
|
|
|
|
|
2018-03-07 01:06:56 +01:00
|
|
|
/* Our proposal can change as feerates change. Input
|
2020-05-26 05:39:40 +02:00
|
|
|
* comparison (ignoring signatures) works pretty well. */
|
|
|
|
if (tal_count(tx_parts->inputs) != out->proposal->tx->wtx->num_inputs)
|
2017-08-23 03:52:17 +02:00
|
|
|
return false;
|
2018-03-07 01:06:56 +01:00
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
for (size_t i = 0; i < tal_count(tx_parts->inputs); i++) {
|
|
|
|
if (!input_similar(tx_parts->inputs[i],
|
|
|
|
&out->proposal->tx->wtx->inputs[i]))
|
2018-03-07 01:06:56 +01:00
|
|
|
return false;
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
|
2019-07-05 06:57:01 +02:00
|
|
|
out->resolved = tal(out, struct resolution);
|
2020-05-26 05:39:40 +02:00
|
|
|
out->resolved->txid = tx_parts->txid;
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("Resolved %s/%s by our proposal %s (%s)",
|
2017-08-23 03:52:17 +02:00
|
|
|
tx_type_name(out->tx_type),
|
|
|
|
output_type_name(out->output_type),
|
|
|
|
tx_type_name(out->proposal->tx_type),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct bitcoin_txid,
|
2018-03-07 01:06:56 +01:00
|
|
|
&out->resolved->txid));
|
2017-08-23 03:52:17 +02:00
|
|
|
|
|
|
|
out->resolved->depth = 0;
|
|
|
|
out->resolved->tx_type = out->proposal->tx_type;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Otherwise, we figure out what happened and then call this. */
|
|
|
|
static void resolved_by_other(struct tracked_output *out,
|
2017-12-18 07:41:52 +01:00
|
|
|
const struct bitcoin_txid *txid,
|
2017-08-23 03:52:17 +02:00
|
|
|
enum tx_type tx_type)
|
|
|
|
{
|
|
|
|
out->resolved = tal(out, struct resolution);
|
|
|
|
out->resolved->txid = *txid;
|
|
|
|
out->resolved->depth = 0;
|
|
|
|
out->resolved->tx_type = tx_type;
|
|
|
|
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("Resolved %s/%s by %s (%s)",
|
2017-08-23 03:52:17 +02:00
|
|
|
tx_type_name(out->tx_type),
|
|
|
|
output_type_name(out->output_type),
|
|
|
|
tx_type_name(tx_type),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct bitcoin_txid, txid));
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void unknown_spend(struct tracked_output *out,
|
2020-05-26 05:39:40 +02:00
|
|
|
const struct tx_parts *tx_parts)
|
2017-08-23 03:52:17 +02:00
|
|
|
{
|
|
|
|
out->resolved = tal(out, struct resolution);
|
2020-05-26 05:39:40 +02:00
|
|
|
out->resolved->txid = tx_parts->txid;
|
2017-08-23 03:52:17 +02:00
|
|
|
out->resolved->depth = 0;
|
|
|
|
out->resolved->tx_type = UNKNOWN_TXTYPE;
|
|
|
|
|
2019-09-08 18:07:19 +02:00
|
|
|
status_broken("Unknown spend of %s/%s by %s",
|
2017-08-23 03:52:17 +02:00
|
|
|
tx_type_name(out->tx_type),
|
|
|
|
output_type_name(out->output_type),
|
2020-05-26 05:39:40 +02:00
|
|
|
type_to_string(tmpctx, struct bitcoin_txid,
|
|
|
|
&tx_parts->txid));
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
static u64 unmask_commit_number(const struct tx_parts *tx,
|
|
|
|
uint32_t locktime,
|
2019-09-09 18:11:24 +02:00
|
|
|
enum side opener,
|
2017-08-23 03:52:17 +02:00
|
|
|
const struct pubkey *local_payment_basepoint,
|
|
|
|
const struct pubkey *remote_payment_basepoint)
|
|
|
|
{
|
|
|
|
u64 obscurer;
|
|
|
|
const struct pubkey *keys[NUM_SIDES];
|
|
|
|
keys[LOCAL] = local_payment_basepoint;
|
|
|
|
keys[REMOTE] = remote_payment_basepoint;
|
|
|
|
|
|
|
|
/* BOLT #3:
|
|
|
|
*
|
2019-01-14 03:22:05 +01:00
|
|
|
* The 48-bit commitment number is obscured by `XOR` with the lower 48 bits of...
|
2017-08-23 03:52:17 +02:00
|
|
|
*/
|
2019-09-09 18:11:24 +02:00
|
|
|
obscurer = commit_number_obscurer(keys[opener], keys[!opener]);
|
2017-08-23 03:52:17 +02:00
|
|
|
|
|
|
|
/* BOLT #3:
|
|
|
|
*
|
2019-01-14 03:22:05 +01:00
|
|
|
* * locktime: upper 8 bits are 0x20, lower 24 bits are the lower 24 bits of the obscured commitment number
|
2017-08-23 03:52:17 +02:00
|
|
|
*...
|
2019-01-14 03:22:05 +01:00
|
|
|
* * `txin[0]` sequence: upper 8 bits are 0x80, lower 24 bits are upper 24 bits of the obscured commitment number
|
2017-08-23 03:52:17 +02:00
|
|
|
*/
|
2020-05-26 05:39:40 +02:00
|
|
|
return ((locktime & 0x00FFFFFF)
|
|
|
|
| (tx->inputs[0]->sequence & (u64)0x00FFFFFF) << 24)
|
2017-08-23 03:52:17 +02:00
|
|
|
^ obscurer;
|
|
|
|
}
|
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
static bool is_mutual_close(const struct tx_parts *tx,
|
2017-08-23 03:52:17 +02:00
|
|
|
const u8 *local_scriptpubkey,
|
2020-04-02 04:35:52 +02:00
|
|
|
const u8 *remote_scriptpubkey,
|
|
|
|
int *local_outnum)
|
2017-08-23 03:52:17 +02:00
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
bool local_matched = false, remote_matched = false;
|
2020-04-02 04:35:52 +02:00
|
|
|
*local_outnum = -1;
|
2017-08-23 03:52:17 +02:00
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
for (i = 0; i < tal_count(tx->outputs); i++) {
|
2017-08-23 03:52:17 +02:00
|
|
|
/* To be paranoid, we only let each one match once. */
|
2019-09-26 00:42:26 +02:00
|
|
|
if (chainparams->is_elements &&
|
2020-05-26 05:39:40 +02:00
|
|
|
tx->outputs[i]->script_len == 0) {
|
2019-05-09 18:55:42 +02:00
|
|
|
/* This is a fee output, ignore please */
|
|
|
|
continue;
|
2020-05-26 05:39:40 +02:00
|
|
|
} else if (wally_tx_output_scripteq(tx->outputs[i],
|
|
|
|
local_scriptpubkey)
|
|
|
|
&& !local_matched) {
|
2020-04-02 04:35:52 +02:00
|
|
|
*local_outnum = i;
|
2017-08-23 03:52:17 +02:00
|
|
|
local_matched = true;
|
2020-05-26 05:39:40 +02:00
|
|
|
} else if (wally_tx_output_scripteq(tx->outputs[i],
|
|
|
|
remote_scriptpubkey)
|
|
|
|
&& !remote_matched)
|
2017-08-23 03:52:17 +02:00
|
|
|
remote_matched = true;
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* We only ever send out one, so matching it is easy. */
|
2017-12-18 07:41:52 +01:00
|
|
|
static bool is_local_commitment(const struct bitcoin_txid *txid,
|
|
|
|
const struct bitcoin_txid *our_broadcast_txid)
|
2017-08-23 03:52:17 +02:00
|
|
|
{
|
2018-07-04 07:30:02 +02:00
|
|
|
return bitcoin_txid_eq(txid, our_broadcast_txid);
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* BOLT #5:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* Outputs that are *resolved* are considered *irrevocably resolved*
|
|
|
|
* once the remote's *resolving* transaction is included in a block at least 100
|
|
|
|
* deep, on the most-work blockchain.
|
2017-08-23 03:52:17 +02:00
|
|
|
*/
|
2018-02-23 06:53:47 +01:00
|
|
|
static size_t num_not_irrevocably_resolved(struct tracked_output **outs)
|
2017-08-23 03:52:17 +02:00
|
|
|
{
|
2018-02-23 06:53:47 +01:00
|
|
|
size_t i, num = 0;
|
2017-08-23 03:52:17 +02:00
|
|
|
|
|
|
|
for (i = 0; i < tal_count(outs); i++) {
|
2018-01-04 04:10:37 +01:00
|
|
|
if (!outs[i]->resolved || outs[i]->resolved->depth < 100)
|
2018-02-23 06:53:47 +01:00
|
|
|
num++;
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
2018-02-23 06:53:47 +01:00
|
|
|
return num;
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
|
2018-02-23 06:53:47 +01:00
|
|
|
static u32 prop_blockheight(const struct tracked_output *out)
|
|
|
|
{
|
|
|
|
return out->tx_blockheight + out->proposal->depth_required;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void billboard_update(struct tracked_output **outs)
|
|
|
|
{
|
|
|
|
const struct tracked_output *best = NULL;
|
|
|
|
|
|
|
|
/* Highest priority is to report on proposals we have */
|
|
|
|
for (size_t i = 0; i < tal_count(outs); i++) {
|
2019-07-05 07:28:20 +02:00
|
|
|
if (!outs[i]->proposal || outs[i]->resolved)
|
2018-02-23 06:53:47 +01:00
|
|
|
continue;
|
|
|
|
if (!best || prop_blockheight(outs[i]) < prop_blockheight(best))
|
|
|
|
best = outs[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (best) {
|
|
|
|
/* If we've broadcast and not seen yet, this happens */
|
|
|
|
if (best->proposal->depth_required <= best->depth) {
|
|
|
|
peer_billboard(false,
|
|
|
|
"%u outputs unresolved: waiting confirmation that we spent %s (%s:%u) using %s",
|
|
|
|
num_not_irrevocably_resolved(outs),
|
|
|
|
output_type_name(best->output_type),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct bitcoin_txid,
|
2018-02-23 06:53:47 +01:00
|
|
|
&best->txid),
|
|
|
|
best->outnum,
|
|
|
|
tx_type_name(best->proposal->tx_type));
|
|
|
|
} else {
|
|
|
|
peer_billboard(false,
|
|
|
|
"%u outputs unresolved: in %u blocks will spend %s (%s:%u) using %s",
|
|
|
|
num_not_irrevocably_resolved(outs),
|
|
|
|
best->proposal->depth_required - best->depth,
|
|
|
|
output_type_name(best->output_type),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct bitcoin_txid,
|
2018-02-23 06:53:47 +01:00
|
|
|
&best->txid),
|
|
|
|
best->outnum,
|
|
|
|
tx_type_name(best->proposal->tx_type));
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now, just report on the last thing we're waiting out. */
|
|
|
|
for (size_t i = 0; i < tal_count(outs); i++) {
|
|
|
|
/* FIXME: Can this happen? No proposal, no resolution? */
|
|
|
|
if (!outs[i]->resolved)
|
|
|
|
continue;
|
|
|
|
if (!best || outs[i]->resolved->depth < best->resolved->depth)
|
|
|
|
best = outs[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (best) {
|
|
|
|
peer_billboard(false,
|
|
|
|
"All outputs resolved:"
|
|
|
|
" waiting %u more blocks before forgetting"
|
|
|
|
" channel",
|
|
|
|
best->resolved->depth < 100
|
|
|
|
? 100 - best->resolved->depth : 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Not sure this can happen, but take last one (there must be one!) */
|
|
|
|
best = outs[tal_count(outs)-1];
|
|
|
|
peer_billboard(false, "%u outputs unresolved: %s is one (depth %u)",
|
|
|
|
num_not_irrevocably_resolved(outs),
|
|
|
|
output_type_name(best->output_type), best->depth);
|
|
|
|
}
|
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
static void unwatch_txid(const struct bitcoin_txid *txid)
|
2017-08-23 03:52:17 +02:00
|
|
|
{
|
|
|
|
u8 *msg;
|
|
|
|
|
2020-08-25 04:15:48 +02:00
|
|
|
msg = towire_onchaind_unwatch_tx(NULL, txid);
|
2017-08-23 03:52:17 +02:00
|
|
|
wire_sync_write(REQ_FD, take(msg));
|
|
|
|
}
|
|
|
|
|
2017-09-20 06:45:41 +02:00
|
|
|
static void handle_htlc_onchain_fulfill(struct tracked_output *out,
|
2020-05-26 05:39:40 +02:00
|
|
|
const struct tx_parts *tx_parts)
|
2017-08-23 03:52:17 +02:00
|
|
|
{
|
2020-05-26 05:39:40 +02:00
|
|
|
const struct wally_tx_witness_item *preimage_item;
|
2017-09-26 06:57:19 +02:00
|
|
|
struct preimage preimage;
|
|
|
|
struct sha256 sha;
|
|
|
|
struct ripemd160 ripemd;
|
|
|
|
|
2018-02-08 22:43:01 +01:00
|
|
|
/* Our HTLC, they filled (must be an HTLC-success tx). */
|
2020-04-02 04:48:39 +02:00
|
|
|
if (out->tx_type == THEIR_UNILATERAL
|
|
|
|
|| out->tx_type == THEIR_REVOKED_UNILATERAL) {
|
2017-09-26 06:57:19 +02:00
|
|
|
/* BOLT #3:
|
|
|
|
*
|
|
|
|
* ## HTLC-Timeout and HTLC-Success Transactions
|
|
|
|
*
|
2017-11-15 07:20:39 +01:00
|
|
|
* ... `txin[0]` witness stack: `0 <remotehtlcsig> <localhtlcsig>
|
2018-06-17 12:13:44 +02:00
|
|
|
* <payment_preimage>` for HTLC-success
|
2017-09-26 06:57:19 +02:00
|
|
|
*/
|
2020-05-26 05:39:40 +02:00
|
|
|
if (tx_parts->inputs[0]->witness->num_items != 5) /* +1 for wscript */
|
2017-09-26 06:57:19 +02:00
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
|
|
"%s/%s spent with weird witness %zu",
|
|
|
|
tx_type_name(out->tx_type),
|
|
|
|
output_type_name(out->output_type),
|
2020-05-26 05:39:40 +02:00
|
|
|
tx_parts->inputs[0]->witness->num_items);
|
2017-09-26 06:57:19 +02:00
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
preimage_item = &tx_parts->inputs[0]->witness->items[3];
|
2017-09-26 06:57:19 +02:00
|
|
|
} else if (out->tx_type == OUR_UNILATERAL) {
|
|
|
|
/* BOLT #3:
|
|
|
|
*
|
|
|
|
* The remote node can redeem the HTLC with the witness:
|
|
|
|
*
|
2017-11-15 07:20:39 +01:00
|
|
|
* <remotehtlcsig> <payment_preimage>
|
2017-09-26 06:57:19 +02:00
|
|
|
*/
|
2020-05-26 05:39:40 +02:00
|
|
|
if (tx_parts->inputs[0]->witness->num_items != 3) /* +1 for wscript */
|
2017-09-26 06:57:19 +02:00
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
|
|
"%s/%s spent with weird witness %zu",
|
|
|
|
tx_type_name(out->tx_type),
|
|
|
|
output_type_name(out->output_type),
|
2020-05-26 05:39:40 +02:00
|
|
|
tx_parts->inputs[0]->witness->num_items);
|
2017-09-26 06:57:19 +02:00
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
preimage_item = &tx_parts->inputs[0]->witness->items[1];
|
2017-09-26 06:57:19 +02:00
|
|
|
} else
|
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
|
|
"onchain_fulfill for %s/%s?",
|
|
|
|
tx_type_name(out->tx_type),
|
|
|
|
output_type_name(out->output_type));
|
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
/* cppcheck-suppress uninitvar - doesn't know status_failed exits? */
|
|
|
|
if (preimage_item->witness_len != sizeof(preimage)) {
|
2020-04-02 04:51:20 +02:00
|
|
|
/* It's possible something terrible happened and we broadcast
|
|
|
|
* an old commitment state, which they're now cleaning up.
|
|
|
|
*
|
|
|
|
* We stumble along.
|
|
|
|
*/
|
|
|
|
if (out->tx_type == OUR_UNILATERAL
|
2020-05-26 05:39:40 +02:00
|
|
|
&& preimage_item->witness_len == PUBKEY_CMPR_LEN) {
|
2020-04-02 04:51:20 +02:00
|
|
|
status_unusual("Our cheat attempt failed, they're "
|
|
|
|
"taking our htlc out (%s)",
|
|
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
|
|
&out->sat));
|
|
|
|
return;
|
|
|
|
}
|
2017-09-26 06:57:19 +02:00
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
|
|
"%s/%s spent with bad witness length %zu",
|
|
|
|
tx_type_name(out->tx_type),
|
|
|
|
output_type_name(out->output_type),
|
2020-05-26 05:39:40 +02:00
|
|
|
preimage_item->witness_len);
|
2020-04-02 04:51:20 +02:00
|
|
|
}
|
2020-05-26 05:39:40 +02:00
|
|
|
memcpy(&preimage, preimage_item->witness, sizeof(preimage));
|
2017-09-26 06:57:19 +02:00
|
|
|
sha256(&sha, &preimage, sizeof(preimage));
|
|
|
|
ripemd160(&ripemd, &sha, sizeof(sha));
|
|
|
|
|
2018-11-22 03:17:29 +01:00
|
|
|
if (!ripemd160_eq(&ripemd, &out->htlc.ripemd))
|
2017-09-26 06:57:19 +02:00
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
|
|
"%s/%s spent with bad preimage %s (ripemd not %s)",
|
|
|
|
tx_type_name(out->tx_type),
|
|
|
|
output_type_name(out->output_type),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct preimage, &preimage),
|
|
|
|
type_to_string(tmpctx, struct ripemd160,
|
2018-11-22 03:17:29 +01:00
|
|
|
&out->htlc.ripemd));
|
2017-09-26 06:57:19 +02:00
|
|
|
|
2020-04-02 04:31:28 +02:00
|
|
|
/* we stash the payment_hash into the tracking_output so we
|
|
|
|
* can pass it along, if needbe, to the coin movement tracker */
|
2020-04-15 05:08:06 +02:00
|
|
|
out->payment_hash = sha;
|
2020-04-02 04:31:28 +02:00
|
|
|
|
2017-09-26 06:57:19 +02:00
|
|
|
/* Tell master we found a preimage. */
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("%s/%s gave us preimage %s",
|
2017-09-26 06:57:19 +02:00
|
|
|
tx_type_name(out->tx_type),
|
|
|
|
output_type_name(out->output_type),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct preimage, &preimage));
|
2017-09-26 06:57:19 +02:00
|
|
|
wire_sync_write(REQ_FD,
|
2020-08-25 04:15:48 +02:00
|
|
|
take(towire_onchaind_extracted_preimage(NULL,
|
2017-09-26 06:57:19 +02:00
|
|
|
&preimage)));
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
static void resolve_htlc_tx(struct tracked_output ***outs,
|
2017-09-20 06:54:16 +02:00
|
|
|
size_t out_index,
|
2020-05-26 05:39:40 +02:00
|
|
|
const struct tx_parts *htlc_tx,
|
2020-04-03 03:46:18 +02:00
|
|
|
u32 tx_blockheight,
|
|
|
|
bool is_replay)
|
2017-09-20 06:54:16 +02:00
|
|
|
{
|
|
|
|
struct tracked_output *out;
|
|
|
|
struct bitcoin_tx *tx;
|
2019-03-22 22:48:04 +01:00
|
|
|
struct amount_sat amt;
|
2019-09-26 21:07:20 +02:00
|
|
|
struct amount_asset asset;
|
2018-03-07 01:06:57 +01:00
|
|
|
enum tx_type tx_type = OUR_DELAYED_RETURN_TO_WALLET;
|
2017-09-20 06:54:16 +02:00
|
|
|
u8 *wscript = bitcoin_wscript_htlc_tx(htlc_tx, to_self_delay[LOCAL],
|
|
|
|
&keyset->self_revocation_key,
|
|
|
|
&keyset->self_delayed_payment_key);
|
|
|
|
|
|
|
|
|
|
|
|
/* BOLT #5:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* - SHOULD resolve the HTLC-timeout transaction by spending it to
|
|
|
|
* a convenient address...
|
|
|
|
* - MUST wait until the `OP_CHECKSEQUENCEVERIFY` delay has passed
|
|
|
|
* (as specified by the remote node's `open_channel`
|
|
|
|
* `to_self_delay` field) before spending that HTLC-timeout
|
|
|
|
* output.
|
2017-09-20 06:54:16 +02:00
|
|
|
*/
|
2020-05-26 05:39:40 +02:00
|
|
|
asset = wally_tx_output_get_amount(htlc_tx->outputs[0]);
|
2019-09-26 21:07:20 +02:00
|
|
|
assert(amount_asset_is_main(&asset));
|
|
|
|
amt = amount_asset_to_sat(&asset);
|
2020-05-26 05:39:40 +02:00
|
|
|
out = new_tracked_output(outs, &htlc_tx->txid,
|
2020-05-26 05:39:40 +02:00
|
|
|
tx_blockheight,
|
2017-09-20 06:54:16 +02:00
|
|
|
(*outs)[out_index]->resolved->tx_type,
|
2019-03-22 22:48:04 +01:00
|
|
|
0, amt,
|
2017-09-20 06:54:16 +02:00
|
|
|
DELAYED_OUTPUT_TO_US,
|
|
|
|
NULL, NULL, NULL);
|
|
|
|
|
|
|
|
/* BOLT #3:
|
|
|
|
*
|
|
|
|
* ## HTLC-Timeout and HTLC-Success Transactions
|
|
|
|
*
|
|
|
|
* These HTLC transactions are almost identical, except the
|
2018-06-17 12:13:44 +02:00
|
|
|
* HTLC-timeout transaction is timelocked.
|
2017-09-20 06:54:16 +02:00
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* ... to collect the output, the local node uses an input with
|
2017-09-20 06:54:16 +02:00
|
|
|
* nSequence `to_self_delay` and a witness stack `<local_delayedsig>
|
|
|
|
* 0`
|
|
|
|
*/
|
2020-03-10 14:11:47 +01:00
|
|
|
tx = tx_to_us(*outs, delayed_payment_to_us, out, to_self_delay[LOCAL],
|
|
|
|
0, NULL, 0, wscript, &tx_type, htlc_feerate);
|
2017-09-20 06:54:16 +02:00
|
|
|
|
2020-04-03 03:46:18 +02:00
|
|
|
propose_resolution(out, tx, to_self_delay[LOCAL], tx_type,
|
|
|
|
is_replay);
|
2017-09-20 06:54:16 +02:00
|
|
|
}
|
|
|
|
|
2017-09-26 23:02:37 +02:00
|
|
|
/* BOLT #5:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* - MUST *resolve* the _remote node's HTLC-timeout transaction_ by spending it
|
|
|
|
* using the revocation private key.
|
|
|
|
* - MUST *resolve* the _remote node's HTLC-success transaction_ by spending it
|
|
|
|
* using the revocation private key.
|
2017-09-26 23:02:37 +02:00
|
|
|
*/
|
2020-05-26 05:39:40 +02:00
|
|
|
static void steal_htlc_tx(struct tracked_output *out,
|
2020-04-02 04:48:39 +02:00
|
|
|
struct tracked_output ***outs,
|
2020-05-26 05:39:40 +02:00
|
|
|
const struct tx_parts *htlc_tx,
|
2020-04-02 04:48:39 +02:00
|
|
|
u32 htlc_tx_blockheight,
|
2020-04-03 03:46:18 +02:00
|
|
|
enum tx_type htlc_tx_type,
|
|
|
|
bool is_replay)
|
2017-09-26 23:02:37 +02:00
|
|
|
{
|
|
|
|
struct bitcoin_tx *tx;
|
2018-03-07 01:06:57 +01:00
|
|
|
enum tx_type tx_type = OUR_PENALTY_TX;
|
2020-04-02 04:48:39 +02:00
|
|
|
struct tracked_output *htlc_out;
|
|
|
|
struct amount_asset asset;
|
|
|
|
struct amount_sat htlc_out_amt, fees;
|
2017-09-26 23:02:37 +02:00
|
|
|
|
2020-04-02 04:48:39 +02:00
|
|
|
u8 *wscript = bitcoin_wscript_htlc_tx(htlc_tx, to_self_delay[LOCAL],
|
|
|
|
&keyset->self_revocation_key,
|
|
|
|
&keyset->self_delayed_payment_key);
|
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
asset = wally_tx_output_get_amount(htlc_tx->outputs[0]);
|
2020-04-02 04:48:39 +02:00
|
|
|
assert(amount_asset_is_main(&asset));
|
|
|
|
htlc_out_amt = amount_asset_to_sat(&asset);
|
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
htlc_out = new_tracked_output(outs,
|
2020-05-26 05:39:40 +02:00
|
|
|
&htlc_tx->txid, htlc_tx_blockheight,
|
2020-04-02 04:48:39 +02:00
|
|
|
htlc_tx_type,
|
|
|
|
/* htlc tx's only have 1 output */
|
|
|
|
0, htlc_out_amt,
|
|
|
|
DELAYED_CHEAT_OUTPUT_TO_THEM,
|
|
|
|
&out->htlc, wscript, NULL);
|
2017-09-26 23:02:37 +02:00
|
|
|
/* BOLT #3:
|
|
|
|
*
|
|
|
|
* To spend this via penalty, the remote node uses a witness stack
|
|
|
|
* `<revocationsig> 1`
|
|
|
|
*/
|
2020-04-02 04:48:39 +02:00
|
|
|
tx = tx_to_us(htlc_out, penalty_to_us, htlc_out,
|
2020-09-08 05:22:41 +02:00
|
|
|
BITCOIN_TX_RBF_SEQUENCE, 0,
|
2020-04-02 04:48:39 +02:00
|
|
|
&ONE, sizeof(ONE),
|
|
|
|
htlc_out->wscript,
|
|
|
|
&tx_type, penalty_feerate);
|
|
|
|
|
|
|
|
/* mark commitment tx htlc output as 'resolved by them' */
|
2020-05-26 05:39:40 +02:00
|
|
|
resolved_by_other(out, &htlc_tx->txid, htlc_tx_type);
|
2020-04-02 04:48:39 +02:00
|
|
|
|
|
|
|
/* for penalties, we record *any* chain fees
|
|
|
|
* paid as coming from our channel balance, so
|
|
|
|
* that our balance ends up at zero */
|
|
|
|
if (!amount_sat_sub(&fees, out->sat, htlc_out->sat))
|
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
|
|
"unable to subtract %s from %s",
|
|
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
|
|
&htlc_out->sat),
|
|
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
|
|
&out->sat));
|
|
|
|
|
|
|
|
status_debug("recording chain fees for peer's htlc tx, that we're about to steal"
|
|
|
|
" the output of. fees: %s",
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &fees));
|
2020-04-03 03:46:18 +02:00
|
|
|
|
|
|
|
if (!is_replay)
|
2020-05-26 05:39:40 +02:00
|
|
|
update_ledger_chain_fees(&htlc_tx->txid, htlc_tx_blockheight, fees);
|
2020-04-02 04:48:39 +02:00
|
|
|
|
|
|
|
/* annnd done! */
|
2020-04-03 03:46:18 +02:00
|
|
|
propose_resolution(htlc_out, tx, 0, tx_type, is_replay);
|
2017-09-26 23:02:37 +02:00
|
|
|
}
|
|
|
|
|
2019-10-04 12:27:48 +02:00
|
|
|
static void onchain_annotate_txout(const struct bitcoin_txid *txid, u32 outnum,
|
|
|
|
enum wallet_tx_type type)
|
2019-05-27 23:40:37 +02:00
|
|
|
{
|
2020-08-25 04:15:48 +02:00
|
|
|
wire_sync_write(REQ_FD, take(towire_onchaind_annotate_txout(
|
2019-10-04 12:27:48 +02:00
|
|
|
tmpctx, txid, outnum, type)));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void onchain_annotate_txin(const struct bitcoin_txid *txid, u32 innum,
|
|
|
|
enum wallet_tx_type type)
|
|
|
|
{
|
2020-08-25 04:15:48 +02:00
|
|
|
wire_sync_write(REQ_FD, take(towire_onchaind_annotate_txin(
|
2019-10-04 12:27:48 +02:00
|
|
|
tmpctx, txid, innum, type)));
|
2019-05-27 23:40:37 +02:00
|
|
|
}
|
2019-10-04 12:27:48 +02:00
|
|
|
|
2017-08-23 03:52:17 +02:00
|
|
|
/* An output has been spent: see if it resolves something we care about. */
|
2020-05-26 05:39:40 +02:00
|
|
|
static void output_spent(struct tracked_output ***outs,
|
2020-05-26 05:39:40 +02:00
|
|
|
const struct tx_parts *tx_parts,
|
2017-08-23 03:52:17 +02:00
|
|
|
u32 input_num,
|
2020-04-03 03:46:18 +02:00
|
|
|
u32 tx_blockheight,
|
|
|
|
bool is_replay)
|
2017-08-23 03:52:17 +02:00
|
|
|
{
|
2017-09-20 06:54:16 +02:00
|
|
|
for (size_t i = 0; i < tal_count(*outs); i++) {
|
|
|
|
struct tracked_output *out = (*outs)[i];
|
|
|
|
if (out->resolved)
|
2017-08-23 03:52:17 +02:00
|
|
|
continue;
|
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
if (!wally_tx_input_spends(tx_parts->inputs[input_num],
|
|
|
|
&out->txid, out->outnum))
|
2017-08-23 03:52:17 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
/* Was this our resolution? */
|
2020-05-26 05:39:40 +02:00
|
|
|
if (resolved_by_proposal(out, tx_parts)) {
|
2017-09-20 06:54:16 +02:00
|
|
|
/* If it's our htlc tx, we need to resolve that, too. */
|
|
|
|
if (out->resolved->tx_type == OUR_HTLC_SUCCESS_TX
|
|
|
|
|| out->resolved->tx_type == OUR_HTLC_TIMEOUT_TX)
|
2020-05-26 05:39:40 +02:00
|
|
|
resolve_htlc_tx(outs, i, tx_parts,
|
2020-04-03 03:46:18 +02:00
|
|
|
tx_blockheight, is_replay);
|
2020-04-02 04:16:32 +02:00
|
|
|
|
2020-04-03 03:46:18 +02:00
|
|
|
if (!is_replay)
|
2020-04-03 23:52:35 +02:00
|
|
|
record_coin_movements(out, tx_blockheight,
|
2020-05-26 05:39:40 +02:00
|
|
|
out->proposal->tx,
|
|
|
|
&tx_parts->txid);
|
2017-08-23 03:52:17 +02:00
|
|
|
return;
|
2017-09-20 06:54:16 +02:00
|
|
|
}
|
2017-08-23 03:52:17 +02:00
|
|
|
|
2017-09-20 06:54:16 +02:00
|
|
|
switch (out->output_type) {
|
2017-08-23 03:52:17 +02:00
|
|
|
case OUTPUT_TO_US:
|
|
|
|
case DELAYED_OUTPUT_TO_US:
|
2020-05-26 05:39:40 +02:00
|
|
|
unknown_spend(out, tx_parts);
|
2020-04-03 03:46:18 +02:00
|
|
|
if (!is_replay)
|
2020-05-26 05:39:40 +02:00
|
|
|
record_coin_loss(&tx_parts->txid,
|
|
|
|
tx_blockheight, out);
|
2017-08-23 03:52:17 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case THEIR_HTLC:
|
2017-09-26 23:02:37 +02:00
|
|
|
if (out->tx_type == THEIR_REVOKED_UNILATERAL) {
|
2020-04-02 04:48:39 +02:00
|
|
|
/* we've actually got a 'new' output here */
|
2020-05-26 05:39:40 +02:00
|
|
|
steal_htlc_tx(out, outs, tx_parts,
|
2020-04-03 03:46:18 +02:00
|
|
|
tx_blockheight, THEIR_HTLC_TIMEOUT_TO_THEM,
|
|
|
|
is_replay);
|
2017-09-26 23:02:37 +02:00
|
|
|
} else {
|
|
|
|
/* We ignore this timeout tx, since we should
|
|
|
|
* resolve by ignoring once we reach depth. */
|
2019-10-04 12:27:48 +02:00
|
|
|
onchain_annotate_txout(
|
2020-05-26 05:39:40 +02:00
|
|
|
&tx_parts->txid, out->outnum,
|
2019-05-27 23:40:37 +02:00
|
|
|
TX_CHANNEL_HTLC_TIMEOUT | TX_THEIRS);
|
2017-09-26 23:02:37 +02:00
|
|
|
}
|
2017-08-23 03:52:17 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case OUR_HTLC:
|
2017-09-26 23:02:37 +02:00
|
|
|
/* The only way they can spend this: fulfill; even
|
|
|
|
* if it's revoked: */
|
|
|
|
/* BOLT #5:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* ## HTLC Output Handling: Local Commitment, Local Offers
|
|
|
|
*...
|
|
|
|
* - MUST extract the payment preimage from the
|
|
|
|
* transaction input witness.
|
|
|
|
*...
|
|
|
|
* ## HTLC Output Handling: Remote Commitment, Local Offers
|
|
|
|
*...
|
|
|
|
* - MUST extract the payment preimage from the
|
|
|
|
* HTLC-success transaction input witness.
|
2017-09-26 23:02:37 +02:00
|
|
|
*/
|
2020-05-26 05:39:40 +02:00
|
|
|
handle_htlc_onchain_fulfill(out, tx_parts);
|
2020-04-02 04:48:39 +02:00
|
|
|
if (out->tx_type == THEIR_REVOKED_UNILATERAL) {
|
2020-05-26 05:39:40 +02:00
|
|
|
steal_htlc_tx(out, outs, tx_parts,
|
2020-04-03 03:46:18 +02:00
|
|
|
tx_blockheight, OUR_HTLC_FULFILL_TO_THEM,
|
|
|
|
is_replay);
|
2020-04-02 04:48:39 +02:00
|
|
|
} else {
|
2018-01-04 04:10:37 +01:00
|
|
|
/* BOLT #5:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* ## HTLC Output Handling: Local Commitment,
|
|
|
|
* Local Offers
|
|
|
|
*...
|
|
|
|
* - if the commitment transaction HTLC output
|
|
|
|
* is spent using the payment preimage, the
|
|
|
|
* output is considered *irrevocably resolved*
|
2018-01-04 04:10:37 +01:00
|
|
|
*/
|
|
|
|
ignore_output(out);
|
2020-04-02 04:51:20 +02:00
|
|
|
|
2020-04-03 03:46:18 +02:00
|
|
|
if (!is_replay)
|
2020-05-26 05:39:40 +02:00
|
|
|
record_htlc_fulfilled(&tx_parts->txid,
|
|
|
|
out,
|
2020-04-03 23:52:35 +02:00
|
|
|
tx_blockheight,
|
|
|
|
false);
|
2019-10-04 12:27:48 +02:00
|
|
|
onchain_annotate_txout(
|
2020-05-26 05:39:40 +02:00
|
|
|
&tx_parts->txid, out->outnum,
|
2019-05-27 23:40:37 +02:00
|
|
|
TX_CHANNEL_HTLC_SUCCESS | TX_THEIRS);
|
2018-01-04 04:10:37 +01:00
|
|
|
}
|
2017-08-23 03:52:17 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case FUNDING_OUTPUT:
|
|
|
|
/* Master should be restarting us, as this implies
|
|
|
|
* that our old tx was unspent. */
|
2017-09-12 06:55:52 +02:00
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
2017-08-23 03:52:17 +02:00
|
|
|
"Funding output spent again!");
|
|
|
|
|
2020-04-02 04:48:39 +02:00
|
|
|
case DELAYED_CHEAT_OUTPUT_TO_THEM:
|
|
|
|
/* They successfully spent a delayed revoked output */
|
2020-05-26 05:39:40 +02:00
|
|
|
resolved_by_other(out, &tx_parts->txid,
|
|
|
|
THEIR_DELAYED_CHEAT);
|
2020-04-03 03:46:18 +02:00
|
|
|
if (!is_replay)
|
2020-05-26 05:39:40 +02:00
|
|
|
record_their_successful_cheat(&tx_parts->txid,
|
2020-04-03 23:52:35 +02:00
|
|
|
tx_blockheight, out);
|
2020-04-02 04:48:39 +02:00
|
|
|
break;
|
2017-08-23 03:52:17 +02:00
|
|
|
/* Um, we don't track these! */
|
|
|
|
case OUTPUT_TO_THEM:
|
|
|
|
case DELAYED_OUTPUT_TO_THEM:
|
2019-05-09 18:55:42 +02:00
|
|
|
case ELEMENTS_FEE:
|
2020-08-14 03:30:42 +02:00
|
|
|
case ANCHOR_TO_US:
|
|
|
|
case ANCHOR_TO_THEM:
|
2017-09-12 06:55:52 +02:00
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
2017-08-23 03:52:17 +02:00
|
|
|
"Tracked spend of %s/%s?",
|
2017-09-20 06:54:16 +02:00
|
|
|
tx_type_name(out->tx_type),
|
|
|
|
output_type_name(out->output_type));
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
struct bitcoin_txid txid;
|
|
|
|
wally_tx_input_get_txid(tx_parts->inputs[input_num], &txid);
|
2017-08-23 03:52:17 +02:00
|
|
|
/* Not interesting to us, so unwatch the tx and all its outputs */
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("Notified about tx %s output %u spend, but we don't care",
|
2019-03-22 22:48:04 +01:00
|
|
|
type_to_string(tmpctx, struct bitcoin_txid, &txid),
|
2020-05-26 05:39:40 +02:00
|
|
|
tx_parts->inputs[input_num]->index);
|
2019-05-27 23:42:38 +02:00
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
unwatch_txid(&tx_parts->txid);
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
|
2017-09-26 23:02:47 +02:00
|
|
|
static void update_resolution_depth(struct tracked_output *out, u32 depth)
|
|
|
|
{
|
2017-09-28 01:47:22 +02:00
|
|
|
bool reached_reasonable_depth;
|
|
|
|
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("%s/%s->%s depth %u",
|
2017-09-26 23:02:47 +02:00
|
|
|
tx_type_name(out->tx_type),
|
|
|
|
output_type_name(out->output_type),
|
|
|
|
tx_type_name(out->resolved->tx_type),
|
|
|
|
depth);
|
|
|
|
|
2017-09-28 01:47:22 +02:00
|
|
|
/* We only set this once. */
|
|
|
|
reached_reasonable_depth = (out->resolved->depth < reasonable_depth
|
|
|
|
&& depth >= reasonable_depth);
|
|
|
|
|
2017-09-26 23:02:47 +02: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.
|
|
|
|
* - once the resolving transaction has reached reasonable depth:
|
|
|
|
* - MUST fail the corresponding incoming HTLC (if any).
|
|
|
|
*/
|
2017-09-28 01:47:22 +02:00
|
|
|
if ((out->resolved->tx_type == OUR_HTLC_TIMEOUT_TX
|
|
|
|
|| out->resolved->tx_type == OUR_HTLC_TIMEOUT_TO_US)
|
|
|
|
&& reached_reasonable_depth) {
|
|
|
|
u8 *msg;
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("%s/%s reached reasonable depth %u",
|
2017-09-28 01:47:22 +02:00
|
|
|
tx_type_name(out->tx_type),
|
|
|
|
output_type_name(out->output_type),
|
|
|
|
depth);
|
2020-08-25 04:15:48 +02:00
|
|
|
msg = towire_onchaind_htlc_timeout(out, &out->htlc);
|
2017-09-28 01:47:22 +02:00
|
|
|
wire_sync_write(REQ_FD, take(msg));
|
2017-09-26 23:02:47 +02:00
|
|
|
}
|
|
|
|
out->resolved->depth = depth;
|
|
|
|
}
|
|
|
|
|
2017-08-23 03:52:17 +02:00
|
|
|
static void tx_new_depth(struct tracked_output **outs,
|
2020-04-03 03:46:18 +02:00
|
|
|
const struct bitcoin_txid *txid, u32 depth,
|
|
|
|
bool is_replay)
|
2017-08-23 03:52:17 +02:00
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
|
2017-09-26 23:02:47 +02:00
|
|
|
/* Special handling for commitment tx reaching depth */
|
2018-07-04 07:30:02 +02:00
|
|
|
if (bitcoin_txid_eq(&outs[0]->resolved->txid, txid)
|
2017-09-26 23:02:47 +02:00
|
|
|
&& depth >= reasonable_depth
|
2017-09-26 23:02:47 +02:00
|
|
|
&& missing_htlc_msgs) {
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("Sending %zu missing htlc messages",
|
2017-09-26 23:02:47 +02:00
|
|
|
tal_count(missing_htlc_msgs));
|
|
|
|
for (i = 0; i < tal_count(missing_htlc_msgs); i++)
|
|
|
|
wire_sync_write(REQ_FD, missing_htlc_msgs[i]);
|
|
|
|
/* Don't do it again. */
|
|
|
|
missing_htlc_msgs = tal_free(missing_htlc_msgs);
|
|
|
|
}
|
|
|
|
|
2017-08-23 03:52:17 +02:00
|
|
|
for (i = 0; i < tal_count(outs); i++) {
|
2018-02-23 06:53:47 +01:00
|
|
|
/* Update output depth. */
|
2018-07-04 07:30:02 +02:00
|
|
|
if (bitcoin_txid_eq(&outs[i]->txid, txid))
|
2018-02-23 06:53:47 +01:00
|
|
|
outs[i]->depth = depth;
|
|
|
|
|
2017-08-23 03:52:17 +02:00
|
|
|
/* Is this tx resolving an output? */
|
|
|
|
if (outs[i]->resolved) {
|
2018-07-04 07:30:02 +02:00
|
|
|
if (bitcoin_txid_eq(&outs[i]->resolved->txid, txid)) {
|
2017-09-26 23:02:47 +02:00
|
|
|
update_resolution_depth(outs[i], depth);
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Otherwise, is this something we have a pending
|
|
|
|
* resolution for? */
|
|
|
|
if (outs[i]->proposal
|
2018-07-04 07:30:02 +02:00
|
|
|
&& bitcoin_txid_eq(&outs[i]->txid, txid)
|
2017-08-23 03:52:17 +02:00
|
|
|
&& depth >= outs[i]->proposal->depth_required) {
|
2020-04-03 03:46:18 +02:00
|
|
|
proposal_meets_depth(outs[i], is_replay);
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
2020-09-08 05:22:41 +02:00
|
|
|
|
|
|
|
/* Otherwise, is this an output whose proposed resolution
|
|
|
|
* we should RBF? */
|
|
|
|
if (outs[i]->proposal
|
|
|
|
&& bitcoin_txid_eq(&outs[i]->txid, txid)
|
|
|
|
&& proposal_is_rbfable(outs[i]->proposal))
|
|
|
|
proposal_should_rbf(outs[i], is_replay);
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-20 06:45:41 +02:00
|
|
|
/* 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.
|
|
|
|
*...
|
|
|
|
* ## HTLC Output Handling: Remote Commitment, Remote Offers
|
|
|
|
*...
|
|
|
|
* A local node:
|
|
|
|
* - if it receives (or already possesses) a payment preimage for an unresolved
|
|
|
|
* HTLC output that it was offered AND for which it has committed to an
|
|
|
|
* outgoing HTLC:
|
|
|
|
* - MUST *resolve* the output by spending it to a convenient address.
|
|
|
|
* - otherwise:
|
|
|
|
* - if the remote node is NOT irrevocably committed to the HTLC:
|
|
|
|
* - MUST NOT *resolve* the output by spending it.
|
2017-09-20 06:45:41 +02:00
|
|
|
*/
|
2017-09-26 23:02:47 +02:00
|
|
|
/* Master makes sure we only get told preimages once other node is committed. */
|
2020-05-26 05:39:40 +02:00
|
|
|
static void handle_preimage(struct tracked_output **outs,
|
2020-04-03 03:46:18 +02:00
|
|
|
const struct preimage *preimage,
|
|
|
|
bool is_replay)
|
2017-08-23 03:52:17 +02:00
|
|
|
{
|
2017-09-20 06:45:41 +02:00
|
|
|
size_t i;
|
|
|
|
struct sha256 sha;
|
|
|
|
struct ripemd160 ripemd;
|
2019-03-21 14:24:43 +01:00
|
|
|
u8 **witness;
|
2017-09-20 06:45:41 +02:00
|
|
|
|
|
|
|
sha256(&sha, preimage, sizeof(*preimage));
|
|
|
|
ripemd160(&ripemd, &sha, sizeof(sha));
|
|
|
|
|
|
|
|
for (i = 0; i < tal_count(outs); i++) {
|
|
|
|
struct bitcoin_tx *tx;
|
2018-12-03 00:15:06 +01:00
|
|
|
struct bitcoin_signature sig;
|
2017-09-20 06:45:41 +02:00
|
|
|
|
|
|
|
if (outs[i]->output_type != THEIR_HTLC)
|
|
|
|
continue;
|
|
|
|
|
2018-11-22 03:17:29 +01:00
|
|
|
if (!ripemd160_eq(&outs[i]->htlc.ripemd, &ripemd))
|
2017-09-20 06:45:41 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
/* Too late? */
|
|
|
|
if (outs[i]->resolved) {
|
2019-09-08 18:07:19 +02:00
|
|
|
status_broken("HTLC already resolved by %s"
|
2017-09-20 06:45:41 +02:00
|
|
|
" when we found preimage",
|
|
|
|
tx_type_name(outs[i]->resolved->tx_type));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-04-02 04:31:28 +02:00
|
|
|
/* stash the payment_hash so we can track this coin movement */
|
2020-04-15 05:08:06 +02:00
|
|
|
outs[i]->payment_hash = sha;
|
2020-04-02 04:31:28 +02:00
|
|
|
|
2017-09-20 06:45:41 +02:00
|
|
|
/* Discard any previous resolution. Could be a timeout,
|
|
|
|
* could be due to multiple identical rhashes in tx. */
|
|
|
|
outs[i]->proposal = tal_free(outs[i]->proposal);
|
|
|
|
|
|
|
|
/* BOLT #5:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
*
|
|
|
|
* ## HTLC Output Handling: Local Commitment, Remote Offers
|
|
|
|
*...
|
|
|
|
* 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.
|
2017-09-20 06:45:41 +02:00
|
|
|
*/
|
|
|
|
if (outs[i]->remote_htlc_sig) {
|
2019-02-21 04:45:55 +01:00
|
|
|
struct amount_msat htlc_amount;
|
2019-02-21 04:45:55 +01:00
|
|
|
if (!amount_sat_to_msat(&htlc_amount, outs[i]->sat))
|
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
|
|
"Overflow in output %zu %s",
|
|
|
|
i,
|
|
|
|
type_to_string(tmpctx,
|
|
|
|
struct amount_sat,
|
|
|
|
&outs[i]->sat));
|
2020-05-26 05:39:40 +02:00
|
|
|
tx = htlc_success_tx(outs[i], chainparams,
|
2019-07-30 16:14:43 +02:00
|
|
|
&outs[i]->txid,
|
2017-09-20 06:45:41 +02:00
|
|
|
outs[i]->outnum,
|
2020-05-21 21:46:19 +02:00
|
|
|
outs[i]->wscript,
|
2019-02-21 04:45:55 +01:00
|
|
|
htlc_amount,
|
2017-09-20 06:45:41 +02:00
|
|
|
to_self_delay[LOCAL],
|
2017-11-17 04:17:48 +01:00
|
|
|
0,
|
2020-08-14 03:30:41 +02:00
|
|
|
keyset, option_anchor_outputs);
|
2018-04-03 06:30:48 +02:00
|
|
|
set_htlc_success_fee(tx, outs[i]->remote_htlc_sig,
|
|
|
|
outs[i]->wscript);
|
2018-07-23 04:23:02 +02:00
|
|
|
hsm_sign_local_htlc_tx(tx, outs[i]->wscript, &sig);
|
2019-03-21 14:24:43 +01:00
|
|
|
witness = bitcoin_witness_htlc_success_tx(
|
2019-03-22 22:48:04 +01:00
|
|
|
tx, &sig, outs[i]->remote_htlc_sig, preimage,
|
2019-03-21 14:24:43 +01:00
|
|
|
outs[i]->wscript);
|
2019-08-21 05:52:42 +02:00
|
|
|
bitcoin_tx_input_set_witness(tx, 0, take(witness));
|
2020-04-03 03:46:18 +02:00
|
|
|
propose_resolution(outs[i], tx, 0, OUR_HTLC_SUCCESS_TX,
|
|
|
|
is_replay);
|
2017-09-20 06:45:41 +02:00
|
|
|
} else {
|
2018-03-07 01:06:57 +01:00
|
|
|
enum tx_type tx_type = THEIR_HTLC_FULFILL_TO_US;
|
|
|
|
|
2017-09-20 06:45:41 +02:00
|
|
|
/* BOLT #5:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* ## HTLC Output Handling: Remote Commitment, Remote
|
|
|
|
* Offers
|
|
|
|
*...
|
|
|
|
* A local node:
|
|
|
|
* - if it receives (or already possesses) a payment
|
|
|
|
* preimage for an unresolved HTLC output that it was
|
|
|
|
* offered AND for which it has committed to an
|
|
|
|
* outgoing HTLC:
|
|
|
|
* - MUST *resolve* the output by spending it to a
|
|
|
|
* convenient address.
|
2017-09-20 06:45:41 +02:00
|
|
|
*/
|
2020-08-14 03:30:42 +02:00
|
|
|
tx = tx_to_us(outs[i], remote_htlc_to_us, outs[i],
|
|
|
|
option_anchor_outputs ? 1 : 0,
|
2020-03-10 14:11:47 +01:00
|
|
|
0, preimage, sizeof(*preimage),
|
|
|
|
outs[i]->wscript, &tx_type,
|
|
|
|
htlc_feerate);
|
2020-04-03 03:46:18 +02:00
|
|
|
propose_resolution(outs[i], tx, 0, tx_type,
|
|
|
|
is_replay);
|
|
|
|
if (!is_replay && tx_type == IGNORING_TINY_PAYMENT) {
|
2020-04-02 04:45:21 +02:00
|
|
|
struct bitcoin_txid txid;
|
|
|
|
bitcoin_txid(tx, &txid);
|
2020-04-03 23:52:35 +02:00
|
|
|
record_htlc_fulfilled(&txid, outs[i], 0, true);
|
2020-04-02 04:45:21 +02:00
|
|
|
}
|
|
|
|
|
2017-09-20 06:45:41 +02:00
|
|
|
}
|
|
|
|
}
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
|
2018-11-22 03:17:29 +01:00
|
|
|
#if DEVELOPER
|
|
|
|
static void memleak_remove_globals(struct htable *memtable, const tal_t *topctx)
|
|
|
|
{
|
|
|
|
if (keyset)
|
2020-09-23 03:37:04 +02:00
|
|
|
memleak_remove_region(memtable, keyset, sizeof(*keyset));
|
|
|
|
memleak_remove_pointer(memtable, remote_per_commitment_point);
|
|
|
|
memleak_remove_pointer(memtable, remote_per_commitment_secret);
|
|
|
|
memleak_remove_pointer(memtable, topctx);
|
|
|
|
memleak_remove_region(memtable,
|
|
|
|
missing_htlc_msgs, tal_bytelen(missing_htlc_msgs));
|
2018-11-22 03:17:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static bool handle_dev_memleak(struct tracked_output **outs, const u8 *msg)
|
|
|
|
{
|
|
|
|
struct htable *memtable;
|
|
|
|
bool found_leak;
|
|
|
|
|
2020-08-25 04:15:48 +02:00
|
|
|
if (!fromwire_onchaind_dev_memleak(msg))
|
2018-11-22 03:17:29 +01:00
|
|
|
return false;
|
|
|
|
|
2020-09-23 03:37:04 +02:00
|
|
|
memtable = memleak_find_allocations(tmpctx, msg, msg);
|
2018-11-22 03:17:29 +01:00
|
|
|
/* Top-level context is parent of outs */
|
|
|
|
memleak_remove_globals(memtable, tal_parent(outs));
|
2020-09-23 03:37:04 +02:00
|
|
|
memleak_remove_region(memtable, outs, tal_bytelen(outs));
|
2018-11-22 03:17:29 +01:00
|
|
|
|
2021-09-06 14:39:27 +02:00
|
|
|
found_leak = dump_memleak(memtable, memleak_status_broken);
|
2018-11-22 03:17:29 +01:00
|
|
|
wire_sync_write(REQ_FD,
|
2020-08-25 04:15:48 +02:00
|
|
|
take(towire_onchaind_dev_memleak_reply(NULL,
|
2018-11-22 03:17:29 +01:00
|
|
|
found_leak)));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
static bool handle_dev_memleak(struct tracked_output **outs, const u8 *msg)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
#endif /* !DEVELOPER */
|
|
|
|
|
2017-08-23 03:52:17 +02:00
|
|
|
/* BOLT #5:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* A node:
|
|
|
|
* - once it has broadcast a funding transaction OR sent a commitment signature
|
|
|
|
* for a commitment transaction that contains an HTLC output:
|
|
|
|
* - until all outputs are *irrevocably resolved*:
|
|
|
|
* - MUST monitor the blockchain for transactions that spend any output that
|
|
|
|
* is NOT *irrevocably resolved*.
|
2017-08-23 03:52:17 +02:00
|
|
|
*/
|
2020-05-26 05:39:40 +02:00
|
|
|
static void wait_for_resolved(struct tracked_output **outs)
|
2017-08-23 03:52:17 +02:00
|
|
|
{
|
2018-02-23 06:53:47 +01:00
|
|
|
billboard_update(outs);
|
|
|
|
|
2018-02-23 06:53:47 +01:00
|
|
|
while (num_not_irrevocably_resolved(outs) != 0) {
|
2017-08-23 03:52:17 +02:00
|
|
|
u8 *msg = wire_sync_read(outs, REQ_FD);
|
2017-12-18 07:41:52 +01:00
|
|
|
struct bitcoin_txid txid;
|
2017-08-23 03:52:17 +02:00
|
|
|
u32 input_num, depth, tx_blockheight;
|
|
|
|
struct preimage preimage;
|
2020-04-03 03:46:18 +02:00
|
|
|
bool is_replay;
|
2020-05-26 05:39:40 +02:00
|
|
|
struct tx_parts *tx_parts;
|
2017-08-23 03:52:17 +02:00
|
|
|
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("Got new message %s",
|
2020-08-25 04:15:48 +02:00
|
|
|
onchaind_wire_name(fromwire_peektype(msg)));
|
2017-08-23 03:52:17 +02:00
|
|
|
|
2020-08-25 04:15:48 +02:00
|
|
|
if (fromwire_onchaind_depth(msg, &txid, &depth, &is_replay))
|
2020-04-03 03:46:18 +02:00
|
|
|
tx_new_depth(outs, &txid, depth, is_replay);
|
2020-08-25 04:15:48 +02:00
|
|
|
else if (fromwire_onchaind_spent(msg, msg, &tx_parts, &input_num,
|
2020-04-03 03:46:18 +02:00
|
|
|
&tx_blockheight, &is_replay)) {
|
2020-05-26 05:39:40 +02:00
|
|
|
output_spent(&outs, tx_parts, input_num, tx_blockheight, is_replay);
|
2020-08-25 04:15:48 +02:00
|
|
|
} else if (fromwire_onchaind_known_preimage(msg, &preimage, &is_replay))
|
2020-05-26 05:39:40 +02:00
|
|
|
handle_preimage(outs, &preimage, is_replay);
|
2018-11-22 03:17:29 +01:00
|
|
|
else if (!handle_dev_memleak(outs, msg))
|
2017-09-12 06:55:52 +02:00
|
|
|
master_badmsg(-1, msg);
|
2018-02-23 06:53:47 +01:00
|
|
|
|
|
|
|
billboard_update(outs);
|
2017-08-23 03:52:17 +02:00
|
|
|
tal_free(msg);
|
2018-03-15 05:30:37 +01:00
|
|
|
clean_tmpctx();
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
2017-10-12 02:25:54 +02:00
|
|
|
|
|
|
|
wire_sync_write(REQ_FD,
|
2020-08-25 04:15:48 +02:00
|
|
|
take(towire_onchaind_all_irrevocably_resolved(outs)));
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
|
2018-02-23 07:23:51 +01:00
|
|
|
static void init_reply(const char *what)
|
2017-08-23 03:52:17 +02:00
|
|
|
{
|
2018-02-23 10:40:50 +01:00
|
|
|
/* Send init_reply first, so billboard gets credited to ONCHAIND */
|
2020-08-25 04:15:48 +02:00
|
|
|
wire_sync_write(REQ_FD, take(towire_onchaind_init_reply(NULL)));
|
2018-02-23 10:40:50 +01:00
|
|
|
peer_billboard(true, what);
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
static void handle_mutual_close(struct tracked_output **outs,
|
|
|
|
const struct tx_parts *tx,
|
2020-04-03 23:52:35 +02:00
|
|
|
u32 tx_blockheight,
|
2020-04-03 03:46:18 +02:00
|
|
|
int our_outnum,
|
|
|
|
bool is_replay)
|
2017-08-23 03:52:17 +02:00
|
|
|
{
|
2020-04-02 04:35:52 +02:00
|
|
|
struct amount_sat our_out;
|
2018-02-23 07:23:51 +01:00
|
|
|
init_reply("Tracking mutual close transaction");
|
2019-10-04 12:27:48 +02:00
|
|
|
|
|
|
|
/* Annotate the first input as close. We can currently only have a
|
|
|
|
* single input for these. */
|
2020-05-26 05:39:40 +02:00
|
|
|
onchain_annotate_txin(&tx->txid, 0, TX_CHANNEL_CLOSE);
|
2017-08-23 03:52:17 +02:00
|
|
|
|
|
|
|
/* BOLT #5:
|
|
|
|
*
|
2019-01-14 03:26:25 +01:00
|
|
|
* A closing transaction *resolves* the funding transaction output.
|
2017-08-23 03:52:17 +02:00
|
|
|
*
|
2019-01-14 03:26:25 +01:00
|
|
|
* In the case of a mutual close, a node need not do anything else, as it has
|
|
|
|
* already agreed to the output, which is sent to its specified `scriptpubkey`
|
2017-08-23 03:52:17 +02:00
|
|
|
*/
|
2020-05-26 05:39:40 +02:00
|
|
|
resolved_by_other(outs[0], &tx->txid, MUTUAL_CLOSE);
|
2017-08-23 03:52:17 +02:00
|
|
|
|
2020-04-03 03:46:18 +02:00
|
|
|
if (!is_replay) {
|
|
|
|
/* It's possible there's no to_us output */
|
|
|
|
if (our_outnum > -1) {
|
|
|
|
struct amount_asset asset;
|
2020-05-26 05:39:40 +02:00
|
|
|
asset = wally_tx_output_get_amount(tx->outputs[our_outnum]);
|
2020-04-03 03:46:18 +02:00
|
|
|
assert(amount_asset_is_main(&asset));
|
|
|
|
our_out = amount_asset_to_sat(&asset);
|
|
|
|
} else
|
|
|
|
our_out = AMOUNT_SAT(0);
|
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
record_mutual_closure(&tx->txid, tx_blockheight,
|
2020-04-03 23:52:35 +02:00
|
|
|
our_out, our_outnum);
|
2020-04-03 03:46:18 +02:00
|
|
|
}
|
2020-04-02 04:35:52 +02:00
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
wait_for_resolved(outs);
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
|
2017-09-16 01:36:06 +02:00
|
|
|
static u8 **derive_htlc_scripts(const struct htlc_stub *htlcs, enum side side)
|
2017-08-23 03:52:17 +02:00
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
u8 **htlc_scripts = tal_arr(htlcs, u8 *, tal_count(htlcs));
|
|
|
|
|
|
|
|
for (i = 0; i < tal_count(htlcs); i++) {
|
|
|
|
if (htlcs[i].owner == side)
|
|
|
|
htlc_scripts[i] = htlc_offered_wscript(htlc_scripts,
|
|
|
|
&htlcs[i].ripemd,
|
2020-08-14 03:30:41 +02:00
|
|
|
keyset,
|
|
|
|
option_anchor_outputs);
|
2017-08-23 03:52:17 +02:00
|
|
|
else {
|
|
|
|
/* FIXME: remove abs_locktime */
|
|
|
|
struct abs_locktime ltime;
|
|
|
|
if (!blocks_to_abs_locktime(htlcs[i].cltv_expiry,
|
|
|
|
<ime))
|
2017-09-12 06:55:52 +02:00
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
2017-08-23 03:52:17 +02:00
|
|
|
"Could not convert cltv_expiry %u to locktime",
|
|
|
|
htlcs[i].cltv_expiry);
|
|
|
|
htlc_scripts[i] = htlc_received_wscript(htlc_scripts,
|
|
|
|
&htlcs[i].ripemd,
|
|
|
|
<ime,
|
2020-08-14 03:30:41 +02:00
|
|
|
keyset,
|
|
|
|
option_anchor_outputs);
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return htlc_scripts;
|
|
|
|
}
|
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
static size_t resolve_our_htlc_ourcommit(struct tracked_output *out,
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
const size_t *matches,
|
|
|
|
const struct htlc_stub *htlcs,
|
2020-04-03 03:46:18 +02:00
|
|
|
u8 **htlc_scripts,
|
|
|
|
bool is_replay)
|
2017-08-23 03:52:17 +02:00
|
|
|
{
|
2018-11-02 22:26:06 +01:00
|
|
|
struct bitcoin_tx *tx = NULL;
|
2018-12-03 00:15:06 +01:00
|
|
|
struct bitcoin_signature localsig;
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
size_t i;
|
2019-02-21 04:45:55 +01:00
|
|
|
struct amount_msat htlc_amount;
|
2019-03-21 14:24:43 +01:00
|
|
|
u8 **witness;
|
2019-02-21 04:45:55 +01:00
|
|
|
|
2019-02-21 04:45:55 +01:00
|
|
|
if (!amount_sat_to_msat(&htlc_amount, out->sat))
|
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
|
|
"Overflow in our_htlc output %s",
|
|
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
|
|
&out->sat));
|
2017-08-23 03:52:17 +02:00
|
|
|
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
assert(tal_count(matches));
|
2017-08-23 03:52:17 +02:00
|
|
|
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
/* These htlcs are all possibilities, but signature will only match
|
|
|
|
* one with the correct cltv: check which that is. */
|
|
|
|
for (i = 0; i < tal_count(matches); i++) {
|
2020-12-03 02:22:01 +01:00
|
|
|
/* Skip over duplicate HTLCs, since we only need one. */
|
|
|
|
if (i > 0
|
|
|
|
&& (htlcs[matches[i]].cltv_expiry
|
|
|
|
== htlcs[matches[i-1]].cltv_expiry))
|
|
|
|
continue;
|
|
|
|
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
/* BOLT #5:
|
|
|
|
*
|
|
|
|
* ## HTLC Output Handling: Local Commitment, Local Offers
|
|
|
|
* ...
|
|
|
|
* - 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.
|
|
|
|
*/
|
2019-07-30 16:14:43 +02:00
|
|
|
tx = htlc_timeout_tx(tmpctx, chainparams,
|
|
|
|
&out->txid, out->outnum,
|
2020-05-21 21:46:19 +02:00
|
|
|
htlc_scripts[matches[i]], htlc_amount,
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
htlcs[matches[i]].cltv_expiry,
|
2020-08-14 03:30:41 +02:00
|
|
|
to_self_delay[LOCAL], 0, keyset,
|
|
|
|
option_anchor_outputs);
|
2017-08-23 03:52:17 +02:00
|
|
|
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
if (set_htlc_timeout_fee(tx, out->remote_htlc_sig,
|
|
|
|
htlc_scripts[matches[i]]))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Since there's been trouble with this before, we go to some length
|
|
|
|
* to give details here! */
|
|
|
|
if (i == tal_count(matches)) {
|
|
|
|
char *cltvs, *wscripts;
|
|
|
|
|
|
|
|
cltvs = tal_fmt(tmpctx, "%u", htlcs[matches[0]].cltv_expiry);
|
|
|
|
wscripts = tal_hex(tmpctx, htlc_scripts[matches[0]]);
|
|
|
|
|
|
|
|
for (i = 1; i < tal_count(matches); i++) {
|
|
|
|
tal_append_fmt(&cltvs, "/%u",
|
|
|
|
htlcs[matches[i]].cltv_expiry);
|
|
|
|
tal_append_fmt(&wscripts, "/%s",
|
|
|
|
tal_hex(tmpctx, htlc_scripts[matches[i]]));
|
|
|
|
}
|
|
|
|
|
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
|
|
"No valid signature found for %zu htlc_timeout_txs"
|
|
|
|
" feerate %u-%u,"
|
2019-02-21 04:45:55 +01:00
|
|
|
" last tx %s, input %s, signature %s,"
|
2020-08-14 03:30:42 +02:00
|
|
|
" cltvs %s wscripts %s"
|
|
|
|
" %s",
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
tal_count(matches),
|
|
|
|
min_possible_feerate, max_possible_feerate,
|
|
|
|
type_to_string(tmpctx, struct bitcoin_tx, tx),
|
2019-02-21 04:45:55 +01:00
|
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
|
|
&out->sat),
|
2018-12-03 00:15:06 +01:00
|
|
|
type_to_string(tmpctx, struct bitcoin_signature,
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
out->remote_htlc_sig),
|
2020-08-14 03:30:42 +02:00
|
|
|
cltvs, wscripts,
|
|
|
|
option_anchor_outputs
|
|
|
|
? "option_anchor_outputs" : "");
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
hsm_sign_local_htlc_tx(tx, htlc_scripts[matches[i]], &localsig);
|
2017-08-23 03:52:17 +02:00
|
|
|
|
2019-03-22 22:48:04 +01:00
|
|
|
witness = bitcoin_witness_htlc_timeout_tx(tx, &localsig,
|
2017-09-20 06:45:41 +02:00
|
|
|
out->remote_htlc_sig,
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
htlc_scripts[matches[i]]);
|
2017-08-23 03:52:17 +02:00
|
|
|
|
2019-08-21 05:52:42 +02:00
|
|
|
bitcoin_tx_input_set_witness(tx, 0, take(witness));
|
2019-03-21 14:24:43 +01:00
|
|
|
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
/* Steals tx onto out */
|
|
|
|
propose_resolution_at_block(out, tx, htlcs[matches[i]].cltv_expiry,
|
2020-04-03 03:46:18 +02:00
|
|
|
OUR_HTLC_TIMEOUT_TX, is_replay);
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
|
|
|
|
return matches[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* wscript for *received* htlcs (ie. our htlcs in their commit tx, or their
|
|
|
|
* htlcs in our commit tx) includes cltv, so they must be the same for all
|
|
|
|
* matching htlcs. Unless, of course, they've found a sha256 clash. */
|
|
|
|
static u32 matches_cltv(const size_t *matches,
|
|
|
|
const struct htlc_stub *htlcs)
|
|
|
|
{
|
|
|
|
for (size_t i = 1; i < tal_count(matches); i++) {
|
|
|
|
assert(matches[i] < tal_count(htlcs));
|
|
|
|
assert(htlcs[matches[i]].cltv_expiry
|
|
|
|
== htlcs[matches[i-1]].cltv_expiry);
|
|
|
|
}
|
|
|
|
return htlcs[matches[0]].cltv_expiry;
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
static size_t resolve_our_htlc_theircommit(struct tracked_output *out,
|
|
|
|
const size_t *matches,
|
|
|
|
const struct htlc_stub *htlcs,
|
2020-04-03 03:46:18 +02:00
|
|
|
u8 **htlc_scripts,
|
|
|
|
bool is_replay)
|
2017-08-23 03:52:17 +02:00
|
|
|
{
|
|
|
|
struct bitcoin_tx *tx;
|
2018-03-07 01:06:57 +01:00
|
|
|
enum tx_type tx_type = OUR_HTLC_TIMEOUT_TO_US;
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
u32 cltv_expiry = matches_cltv(matches, htlcs);
|
2017-08-23 03:52:17 +02:00
|
|
|
|
|
|
|
/* BOLT #5:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* ## HTLC Output Handling: Remote Commitment, Local Offers
|
2017-08-23 03:52:17 +02:00
|
|
|
* ...
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* - if the commitment transaction HTLC output has *timed out* AND NOT
|
|
|
|
* been *resolved*:
|
|
|
|
* - MUST *resolve* the output, by spending it to a convenient
|
|
|
|
* address.
|
2017-08-23 03:52:17 +02:00
|
|
|
*/
|
2020-08-14 03:30:42 +02:00
|
|
|
tx = tx_to_us(out, remote_htlc_to_us, out,
|
|
|
|
option_anchor_outputs ? 1 : 0,
|
|
|
|
cltv_expiry, NULL, 0,
|
2020-03-10 14:11:47 +01:00
|
|
|
htlc_scripts[matches[0]], &tx_type, htlc_feerate);
|
2017-08-23 03:52:17 +02:00
|
|
|
|
2020-04-03 03:46:18 +02:00
|
|
|
propose_resolution_at_block(out, tx, cltv_expiry, tx_type, is_replay);
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
|
|
|
|
/* They're all equivalent: might as well use first one. */
|
|
|
|
return matches[0];
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
/* Returns which htlcs it chose to use of matches[] */
|
|
|
|
static size_t resolve_their_htlc(struct tracked_output *out,
|
|
|
|
const size_t *matches,
|
|
|
|
const struct htlc_stub *htlcs,
|
2020-04-03 03:46:18 +02:00
|
|
|
u8 **htlc_scripts,
|
|
|
|
bool is_replay)
|
2017-08-23 03:52:17 +02:00
|
|
|
{
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
size_t which_htlc;
|
|
|
|
|
2017-08-23 03:52:17 +02:00
|
|
|
/* BOLT #5:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* ## HTLC Output Handling: Remote Commitment, Remote Offers
|
2017-08-23 03:52:17 +02:00
|
|
|
*...
|
2018-06-17 12:13:44 +02:00
|
|
|
* ### Requirements
|
2017-09-26 23:02:47 +02:00
|
|
|
*...
|
|
|
|
* If not otherwise resolved, once the HTLC output has expired, it is
|
|
|
|
* considered *irrevocably resolved*.
|
2017-08-23 03:52:17 +02:00
|
|
|
*/
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
|
|
|
|
/* BOLT #5:
|
|
|
|
*
|
|
|
|
* ## HTLC Output Handling: Local Commitment, Remote Offers
|
|
|
|
*...
|
|
|
|
* ### Requirements
|
|
|
|
*...
|
|
|
|
* If not otherwise resolved, once the HTLC output has expired, it is
|
|
|
|
* considered *irrevocably resolved*.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* The two cases are identical as far as default handling goes.
|
|
|
|
* But in the remote commitment / remote offer (ie. caller is
|
|
|
|
* handle_their_unilateral), htlcs which match may have different cltvs.
|
|
|
|
* So wait until the worst case (largest HTLC). */
|
|
|
|
assert(tal_count(matches));
|
|
|
|
which_htlc = matches[0];
|
|
|
|
for (size_t i = 1; i < tal_count(matches); i++) {
|
|
|
|
if (htlcs[matches[i]].cltv_expiry > htlcs[which_htlc].cltv_expiry)
|
|
|
|
which_htlc = matches[i];
|
|
|
|
}
|
|
|
|
|
2017-08-23 03:52:17 +02:00
|
|
|
/* If we hit timeout depth, resolve by ignoring. */
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
propose_resolution_at_block(out, NULL, htlcs[which_htlc].cltv_expiry,
|
2020-04-03 03:46:18 +02:00
|
|
|
THEIR_HTLC_TIMEOUT_TO_THEM, is_replay);
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
return which_htlc;
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
/* Return tal_arr of htlc indexes. */
|
|
|
|
static const size_t *match_htlc_output(const tal_t *ctx,
|
2020-05-26 05:39:40 +02:00
|
|
|
const struct wally_tx_output *out,
|
|
|
|
u8 **htlc_scripts)
|
2017-08-23 03:52:17 +02:00
|
|
|
{
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
size_t *matches = tal_arr(ctx, size_t, 0);
|
2020-05-26 05:39:40 +02:00
|
|
|
const u8 *script = tal_dup_arr(tmpctx, u8, out->script, out->script_len,
|
|
|
|
0);
|
2017-08-23 03:52:17 +02:00
|
|
|
/* Must be a p2wsh output */
|
2020-05-26 05:39:40 +02:00
|
|
|
if (!is_p2wsh(script, NULL))
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
return matches;
|
2017-08-23 03:52:17 +02:00
|
|
|
|
|
|
|
for (size_t i = 0; i < tal_count(htlc_scripts); i++) {
|
|
|
|
struct sha256 sha;
|
|
|
|
if (!htlc_scripts[i])
|
|
|
|
continue;
|
|
|
|
|
2018-07-28 08:00:16 +02:00
|
|
|
sha256(&sha, htlc_scripts[i], tal_count(htlc_scripts[i]));
|
2019-03-22 22:48:04 +01:00
|
|
|
if (memeq(script + 2, tal_count(script) - 2, &sha, sizeof(sha)))
|
2019-01-15 04:51:27 +01:00
|
|
|
tal_arr_expand(&matches, i);
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
return matches;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* They must all be in the same direction, since the scripts are different for
|
|
|
|
* each dir. Unless, of course, they've found a sha256 clash. */
|
|
|
|
static enum side matches_direction(const size_t *matches,
|
|
|
|
const struct htlc_stub *htlcs)
|
|
|
|
{
|
|
|
|
for (size_t i = 1; i < tal_count(matches); i++) {
|
|
|
|
assert(matches[i] < tal_count(htlcs));
|
|
|
|
assert(htlcs[matches[i]].owner == htlcs[matches[i-1]].owner);
|
|
|
|
}
|
|
|
|
return htlcs[matches[0]].owner;
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
|
2017-09-26 23:02:47 +02:00
|
|
|
/* Tell master about any we didn't use, if it wants to know. */
|
|
|
|
static void note_missing_htlcs(u8 **htlc_scripts,
|
|
|
|
const struct htlc_stub *htlcs,
|
|
|
|
const bool *tell_if_missing,
|
|
|
|
const bool *tell_immediately)
|
|
|
|
{
|
|
|
|
for (size_t i = 0; i < tal_count(htlcs); i++) {
|
|
|
|
u8 *msg;
|
|
|
|
|
|
|
|
/* Used. */
|
|
|
|
if (!htlc_scripts[i])
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* Doesn't care. */
|
|
|
|
if (!tell_if_missing[i])
|
|
|
|
continue;
|
|
|
|
|
2020-08-25 04:15:48 +02:00
|
|
|
msg = towire_onchaind_missing_htlc_output(missing_htlc_msgs,
|
2017-09-26 23:02:47 +02:00
|
|
|
&htlcs[i]);
|
|
|
|
if (tell_immediately[i])
|
|
|
|
wire_sync_write(REQ_FD, take(msg));
|
2018-09-27 02:19:24 +02:00
|
|
|
else
|
2019-01-15 04:51:27 +01:00
|
|
|
tal_arr_expand(&missing_htlc_msgs, msg);
|
2017-09-26 23:02:47 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-14 03:30:42 +02:00
|
|
|
static void get_anchor_scriptpubkeys(const tal_t *ctx, u8 **anchor)
|
|
|
|
{
|
|
|
|
if (!option_anchor_outputs) {
|
|
|
|
anchor[LOCAL] = anchor[REMOTE] = NULL;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (enum side side = 0; side < NUM_SIDES; side++) {
|
|
|
|
u8 *wscript = bitcoin_wscript_anchor(tmpctx,
|
|
|
|
&funding_pubkey[side]);
|
|
|
|
anchor[side] = scriptpubkey_p2wsh(ctx, wscript);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-14 03:30:42 +02:00
|
|
|
static u8 *scriptpubkey_to_remote(const tal_t *ctx,
|
2021-06-15 22:08:44 +02:00
|
|
|
const struct pubkey *remotekey,
|
|
|
|
u32 csv_lock)
|
2020-08-14 03:30:42 +02:00
|
|
|
{
|
2021-04-06 03:21:18 +02:00
|
|
|
/* BOLT #3:
|
2020-08-14 03:30:42 +02:00
|
|
|
*
|
|
|
|
* #### `to_remote` Output
|
|
|
|
*
|
|
|
|
* If `option_anchor_outputs` applies to the commitment
|
|
|
|
* transaction, the `to_remote` output is encumbered by a one
|
|
|
|
* block csv lock.
|
|
|
|
* <remote_pubkey> OP_CHECKSIGVERIFY 1 OP_CHECKSEQUENCEVERIFY
|
|
|
|
*
|
|
|
|
*...
|
|
|
|
* Otherwise, this output is a simple P2WPKH to `remotepubkey`.
|
|
|
|
*/
|
|
|
|
if (option_anchor_outputs) {
|
|
|
|
return scriptpubkey_p2wsh(ctx,
|
|
|
|
anchor_to_remote_redeem(tmpctx,
|
2021-06-15 22:08:44 +02:00
|
|
|
remotekey,
|
|
|
|
csv_lock));
|
2020-08-14 03:30:42 +02:00
|
|
|
} else {
|
|
|
|
return scriptpubkey_p2wpkh(ctx, remotekey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-16 20:09:32 +02:00
|
|
|
static void our_unilateral_to_us(struct tracked_output ***outs,
|
|
|
|
const struct tx_parts *tx,
|
|
|
|
u32 tx_blockheight,
|
|
|
|
size_t index,
|
|
|
|
struct amount_sat amt,
|
|
|
|
u16 sequence,
|
|
|
|
const u8 *local_scriptpubkey,
|
|
|
|
const u8 *local_wscript,
|
|
|
|
bool is_replay)
|
|
|
|
{
|
|
|
|
struct bitcoin_tx *to_us;
|
|
|
|
struct tracked_output *out;
|
|
|
|
enum tx_type tx_type = OUR_DELAYED_RETURN_TO_WALLET;
|
|
|
|
|
|
|
|
/* BOLT #5:
|
|
|
|
*
|
|
|
|
* A node:
|
|
|
|
* - upon discovering its *local commitment
|
|
|
|
* transaction*:
|
|
|
|
* - SHOULD spend the `to_local` output to a
|
|
|
|
* convenient address.
|
|
|
|
* - MUST wait until the `OP_CHECKSEQUENCEVERIFY`
|
|
|
|
* delay has passed (as specified by the remote
|
|
|
|
* node's `to_self_delay` field) before spending
|
|
|
|
* the output.
|
|
|
|
*/
|
|
|
|
out = new_tracked_output(outs, &tx->txid, tx_blockheight,
|
|
|
|
OUR_UNILATERAL, index,
|
|
|
|
amt,
|
|
|
|
DELAYED_OUTPUT_TO_US,
|
|
|
|
NULL, NULL, NULL);
|
|
|
|
/* BOLT #3:
|
|
|
|
*
|
|
|
|
* 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> <>
|
|
|
|
*/
|
|
|
|
to_us = tx_to_us(out, delayed_payment_to_us, out,
|
|
|
|
sequence, 0, NULL, 0,
|
|
|
|
local_wscript, &tx_type,
|
|
|
|
delayed_to_us_feerate);
|
|
|
|
|
|
|
|
/* BOLT #5:
|
|
|
|
*
|
|
|
|
* Note: if the output is spent (as recommended), the
|
|
|
|
* output is *resolved* by the spending transaction
|
|
|
|
*/
|
|
|
|
propose_resolution(out, to_us, sequence, tx_type, is_replay);
|
|
|
|
}
|
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
static void handle_our_unilateral(const struct tx_parts *tx,
|
2017-08-23 03:52:17 +02:00
|
|
|
u32 tx_blockheight,
|
2018-07-23 04:23:02 +02:00
|
|
|
const struct basepoints basepoints[NUM_SIDES],
|
2017-08-23 03:52:17 +02:00
|
|
|
const struct htlc_stub *htlcs,
|
2017-09-26 23:02:47 +02:00
|
|
|
const bool *tell_if_missing,
|
|
|
|
const bool *tell_immediately,
|
2021-06-16 20:09:32 +02:00
|
|
|
const enum side opener,
|
2020-08-13 19:45:02 +02:00
|
|
|
const struct bitcoin_signature *remote_htlc_sigs,
|
2020-04-03 03:46:18 +02:00
|
|
|
struct tracked_output **outs,
|
|
|
|
bool is_replay)
|
2017-08-23 03:52:17 +02:00
|
|
|
{
|
|
|
|
u8 **htlc_scripts;
|
2020-08-14 03:30:42 +02:00
|
|
|
u8 *local_wscript, *script[NUM_SIDES], *anchor[NUM_SIDES];
|
2017-08-23 03:52:17 +02:00
|
|
|
struct pubkey local_per_commitment_point;
|
2017-09-16 01:36:06 +02:00
|
|
|
struct keyset *ks;
|
2017-08-23 03:52:17 +02:00
|
|
|
size_t i;
|
2020-04-02 04:43:59 +02:00
|
|
|
struct amount_sat their_outs = AMOUNT_SAT(0), our_outs = AMOUNT_SAT(0);
|
2017-08-23 03:52:17 +02:00
|
|
|
|
2018-02-23 07:23:51 +01:00
|
|
|
init_reply("Tracking our own unilateral close");
|
2020-05-26 05:39:40 +02:00
|
|
|
onchain_annotate_txin(&tx->txid, 0, TX_CHANNEL_UNILATERAL);
|
2017-08-23 03:52:17 +02:00
|
|
|
|
|
|
|
/* BOLT #5:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* In this case, a node discovers its *local commitment transaction*,
|
|
|
|
* which *resolves* the funding transaction output.
|
2017-08-23 03:52:17 +02:00
|
|
|
*/
|
2020-05-26 05:39:40 +02:00
|
|
|
resolved_by_other(outs[0], &tx->txid, OUR_UNILATERAL);
|
2017-08-23 03:52:17 +02:00
|
|
|
|
|
|
|
/* Figure out what delayed to-us output looks like */
|
2018-07-23 04:23:03 +02:00
|
|
|
hsm_get_per_commitment_point(&local_per_commitment_point);
|
2017-08-23 03:52:17 +02:00
|
|
|
|
2017-09-16 01:36:06 +02:00
|
|
|
/* keyset is const, we need a non-const ptr to set it up */
|
|
|
|
keyset = ks = tal(tx, struct keyset);
|
2017-08-23 03:52:17 +02:00
|
|
|
if (!derive_keyset(&local_per_commitment_point,
|
2018-07-23 04:23:02 +02:00
|
|
|
&basepoints[LOCAL],
|
|
|
|
&basepoints[REMOTE],
|
2021-06-04 07:13:47 +02:00
|
|
|
commit_num >= static_remotekey_start[LOCAL],
|
2017-09-16 01:36:06 +02:00
|
|
|
ks))
|
2017-09-12 06:55:52 +02:00
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
2017-08-23 03:52:17 +02:00
|
|
|
"Deriving keyset for %"PRIu64, commit_num);
|
|
|
|
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("Deconstructing unilateral tx: %"PRIu64
|
2017-08-23 03:52:17 +02:00
|
|
|
" using keyset: "
|
|
|
|
" self_revocation_key: %s"
|
|
|
|
" self_delayed_payment_key: %s"
|
|
|
|
" self_payment_key: %s"
|
2017-11-15 07:16:39 +01:00
|
|
|
" other_payment_key: %s"
|
|
|
|
" self_htlc_key: %s"
|
|
|
|
" other_htlc_key: %s",
|
2017-08-23 03:52:17 +02:00
|
|
|
commit_num,
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2017-09-16 01:36:06 +02:00
|
|
|
&keyset->self_revocation_key),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2017-09-16 01:36:06 +02:00
|
|
|
&keyset->self_delayed_payment_key),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2017-09-16 01:36:06 +02:00
|
|
|
&keyset->self_payment_key),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2017-11-15 07:16:39 +01:00
|
|
|
&keyset->other_payment_key),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2017-11-15 07:16:39 +01:00
|
|
|
&keyset->self_htlc_key),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2017-11-15 07:16:39 +01:00
|
|
|
&keyset->other_htlc_key));
|
2017-08-23 03:52:17 +02:00
|
|
|
|
2021-06-16 19:44:51 +02:00
|
|
|
local_wscript = to_self_wscript(tmpctx, to_self_delay[LOCAL],
|
|
|
|
1, keyset);
|
2017-08-23 03:52:17 +02:00
|
|
|
|
|
|
|
/* Figure out what to-us output looks like. */
|
|
|
|
script[LOCAL] = scriptpubkey_p2wsh(tmpctx, local_wscript);
|
|
|
|
|
|
|
|
/* Figure out what direct to-them output looks like. */
|
2020-08-14 03:30:42 +02:00
|
|
|
script[REMOTE] = scriptpubkey_to_remote(tmpctx,
|
2021-06-16 19:44:51 +02:00
|
|
|
&keyset->other_payment_key, 1);
|
2017-08-23 03:52:17 +02:00
|
|
|
|
|
|
|
/* Calculate all the HTLC scripts so we can match them */
|
2017-09-16 01:36:06 +02:00
|
|
|
htlc_scripts = derive_htlc_scripts(htlcs, LOCAL);
|
2017-08-23 03:52:17 +02:00
|
|
|
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("Script to-me: %u: %s (%s)",
|
2017-09-16 01:37:06 +02:00
|
|
|
to_self_delay[LOCAL],
|
2018-03-15 05:30:38 +01:00
|
|
|
tal_hex(tmpctx, script[LOCAL]),
|
|
|
|
tal_hex(tmpctx, local_wscript));
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("Script to-them: %s",
|
2018-03-15 05:30:38 +01:00
|
|
|
tal_hex(tmpctx, script[REMOTE]));
|
2017-08-23 03:52:17 +02:00
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
for (i = 0; i < tal_count(tx->outputs); i++) {
|
|
|
|
if (tx->outputs[i]->script == NULL)
|
2019-09-25 14:45:34 +02:00
|
|
|
continue;
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("Output %zu: %s", i,
|
2020-05-26 05:39:40 +02:00
|
|
|
tal_hexstr(tmpctx, tx->outputs[i]->script,
|
|
|
|
tx->outputs[i]->script_len));
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
|
2020-08-14 03:30:42 +02:00
|
|
|
get_anchor_scriptpubkeys(tmpctx, anchor);
|
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
for (i = 0; i < tal_count(tx->outputs); i++) {
|
2017-08-23 03:52:17 +02:00
|
|
|
struct tracked_output *out;
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
const size_t *matches;
|
|
|
|
size_t which_htlc;
|
2020-05-26 05:39:40 +02:00
|
|
|
struct amount_asset asset = wally_tx_output_get_amount(tx->outputs[i]);
|
2019-09-26 21:07:20 +02:00
|
|
|
struct amount_sat amt;
|
|
|
|
|
|
|
|
assert(amount_asset_is_main(&asset));
|
|
|
|
amt = amount_asset_to_sat(&asset);
|
2017-08-23 03:52:17 +02:00
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
if (chainparams->is_elements
|
|
|
|
&& tx->outputs[i]->script_len == 0) {
|
2019-05-09 18:55:42 +02:00
|
|
|
status_debug("OUTPUT %zu is a fee output", i);
|
|
|
|
/* An empty script simply means that that this is a
|
|
|
|
* fee output. */
|
2020-05-26 05:39:40 +02:00
|
|
|
out = new_tracked_output(&outs,
|
2020-05-26 05:39:40 +02:00
|
|
|
&tx->txid, tx_blockheight,
|
2019-05-09 18:55:42 +02:00
|
|
|
OUR_UNILATERAL, i,
|
|
|
|
amt,
|
|
|
|
ELEMENTS_FEE,
|
|
|
|
NULL, NULL, NULL);
|
|
|
|
ignore_output(out);
|
|
|
|
continue;
|
2020-05-26 05:39:40 +02:00
|
|
|
} else if (script[LOCAL]
|
|
|
|
&& wally_tx_output_scripteq(tx->outputs[i],
|
|
|
|
script[LOCAL])) {
|
2021-06-16 20:09:32 +02:00
|
|
|
our_unilateral_to_us(&outs, tx, tx_blockheight,
|
|
|
|
i, amt, to_self_delay[LOCAL],
|
|
|
|
script[LOCAL],
|
|
|
|
local_wscript, is_replay);
|
2017-08-23 03:52:17 +02:00
|
|
|
|
|
|
|
script[LOCAL] = NULL;
|
2020-04-02 04:43:59 +02:00
|
|
|
add_amt(&our_outs, amt);
|
2017-08-23 03:52:17 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (script[REMOTE]
|
2020-05-26 05:39:40 +02:00
|
|
|
&& wally_tx_output_scripteq(tx->outputs[i],
|
|
|
|
script[REMOTE])) {
|
2017-08-23 03:52:17 +02:00
|
|
|
/* BOLT #5:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* - MAY ignore the `to_remote` output.
|
|
|
|
* - Note: No action is required by the local
|
|
|
|
* node, as `to_remote` is considered *resolved*
|
|
|
|
* by the commitment transaction itself.
|
|
|
|
*/
|
2020-05-26 05:39:40 +02:00
|
|
|
out = new_tracked_output(&outs, &tx->txid, tx_blockheight,
|
2017-08-23 03:52:17 +02:00
|
|
|
OUR_UNILATERAL, i,
|
2019-03-22 22:48:04 +01:00
|
|
|
amt,
|
2017-09-20 06:45:41 +02:00
|
|
|
OUTPUT_TO_THEM,
|
|
|
|
NULL, NULL, NULL);
|
2017-08-23 03:52:17 +02:00
|
|
|
ignore_output(out);
|
|
|
|
script[REMOTE] = NULL;
|
2020-04-02 04:43:59 +02:00
|
|
|
add_amt(&their_outs, amt);
|
2017-08-23 03:52:17 +02:00
|
|
|
continue;
|
|
|
|
}
|
2020-08-14 03:30:42 +02:00
|
|
|
if (anchor[LOCAL]
|
|
|
|
&& wally_tx_output_scripteq(tx->outputs[i],
|
|
|
|
anchor[LOCAL])) {
|
|
|
|
/* FIXME: We should be able to spend this! */
|
|
|
|
out = new_tracked_output(&outs, &tx->txid,
|
|
|
|
tx_blockheight,
|
|
|
|
OUR_UNILATERAL, i,
|
|
|
|
amt,
|
|
|
|
ANCHOR_TO_US,
|
|
|
|
NULL, NULL, NULL);
|
|
|
|
ignore_output(out);
|
|
|
|
anchor[LOCAL] = NULL;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (anchor[REMOTE]
|
|
|
|
&& wally_tx_output_scripteq(tx->outputs[i],
|
|
|
|
anchor[REMOTE])) {
|
|
|
|
out = new_tracked_output(&outs, &tx->txid,
|
|
|
|
tx_blockheight,
|
|
|
|
OUR_UNILATERAL, i,
|
|
|
|
amt,
|
|
|
|
ANCHOR_TO_THEM,
|
|
|
|
NULL, NULL, NULL);
|
|
|
|
ignore_output(out);
|
|
|
|
anchor[REMOTE] = NULL;
|
|
|
|
continue;
|
|
|
|
}
|
2017-08-23 03:52:17 +02:00
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
matches = match_htlc_output(tmpctx, tx->outputs[i], htlc_scripts);
|
2017-09-12 06:55:52 +02:00
|
|
|
/* FIXME: limp along when this happens! */
|
2019-05-27 23:40:37 +02:00
|
|
|
if (tal_count(matches) == 0) {
|
2021-06-16 20:09:32 +02:00
|
|
|
bool found = false;
|
|
|
|
|
|
|
|
/* Maybe they're using option_will_fund? */
|
|
|
|
if (opener == REMOTE && script[LOCAL]) {
|
|
|
|
status_debug("Grinding for our to_local");
|
|
|
|
/* We already tried `1` */
|
|
|
|
for (size_t csv = 2;
|
|
|
|
csv <= LEASE_RATE_DURATION;
|
|
|
|
csv++) {
|
|
|
|
|
|
|
|
local_wscript
|
|
|
|
= to_self_wscript(tmpctx,
|
|
|
|
to_self_delay[LOCAL],
|
|
|
|
csv, keyset);
|
|
|
|
|
|
|
|
script[LOCAL]
|
|
|
|
= scriptpubkey_p2wsh(tmpctx,
|
|
|
|
local_wscript);
|
|
|
|
if (!wally_tx_output_scripteq(
|
|
|
|
tx->outputs[i],
|
|
|
|
script[LOCAL]))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
our_unilateral_to_us(&outs, tx,
|
|
|
|
tx_blockheight,
|
|
|
|
i, amt,
|
|
|
|
max(to_self_delay[LOCAL], csv),
|
|
|
|
script[LOCAL],
|
|
|
|
local_wscript,
|
|
|
|
is_replay);
|
|
|
|
|
|
|
|
script[LOCAL] = NULL;
|
|
|
|
add_amt(&our_outs, amt);
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else if (opener == LOCAL && script[REMOTE]) {
|
|
|
|
status_debug("Grinding for to_remote (ours)");
|
|
|
|
/* We already tried `1` */
|
|
|
|
for (size_t csv = 2;
|
|
|
|
csv <= LEASE_RATE_DURATION;
|
|
|
|
csv++) {
|
|
|
|
|
|
|
|
script[REMOTE]
|
|
|
|
= scriptpubkey_to_remote(tmpctx,
|
|
|
|
&keyset->other_payment_key,
|
|
|
|
csv);
|
|
|
|
|
|
|
|
if (!wally_tx_output_scripteq(tx->outputs[i], script[REMOTE]))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* BOLT #5:
|
|
|
|
*
|
|
|
|
* - MAY ignore the `to_remote` output.
|
|
|
|
* - Note: No action is required by the local
|
|
|
|
* node, as `to_remote` is considered *resolved*
|
|
|
|
* by the commitment transaction itself.
|
|
|
|
*/
|
|
|
|
out = new_tracked_output(&outs, &tx->txid, tx_blockheight,
|
|
|
|
OUR_UNILATERAL, i,
|
|
|
|
amt,
|
|
|
|
OUTPUT_TO_THEM,
|
|
|
|
NULL, NULL, NULL);
|
|
|
|
ignore_output(out);
|
|
|
|
script[REMOTE] = NULL;
|
|
|
|
add_amt(&their_outs, amt);
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (found)
|
|
|
|
continue;
|
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
onchain_annotate_txout(&tx->txid, i, TX_CHANNEL_PENALTY | TX_THEIRS);
|
2017-09-12 06:55:52 +02:00
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
2017-08-23 03:52:17 +02:00
|
|
|
"Could not find resolution for output %zu",
|
|
|
|
i);
|
2019-05-27 23:40:37 +02:00
|
|
|
}
|
2017-08-23 03:52:17 +02:00
|
|
|
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
if (matches_direction(matches, htlcs) == LOCAL) {
|
2017-08-23 03:52:17 +02:00
|
|
|
/* BOLT #5:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* - MUST handle HTLCs offered by itself as specified
|
|
|
|
* in [HTLC Output Handling: Local Commitment,
|
|
|
|
* Local Offers]
|
|
|
|
*/
|
2020-05-26 05:39:40 +02:00
|
|
|
out = new_tracked_output(&outs, &tx->txid,
|
2017-08-23 03:52:17 +02:00
|
|
|
tx_blockheight,
|
|
|
|
OUR_UNILATERAL, i,
|
2019-03-22 22:48:04 +01:00
|
|
|
amt,
|
2017-09-20 06:45:41 +02:00
|
|
|
OUR_HTLC,
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
NULL, NULL,
|
2017-09-20 06:45:41 +02:00
|
|
|
remote_htlc_sigs);
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
/* Tells us which htlc to use */
|
2020-05-26 05:39:40 +02:00
|
|
|
which_htlc = resolve_our_htlc_ourcommit(out, matches,
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
htlcs,
|
2020-04-03 03:46:18 +02:00
|
|
|
htlc_scripts,
|
|
|
|
is_replay);
|
2020-04-02 04:43:59 +02:00
|
|
|
add_amt(&our_outs, amt);
|
2017-08-23 03:52:17 +02:00
|
|
|
} else {
|
2020-05-26 05:39:40 +02:00
|
|
|
out = new_tracked_output(&outs, &tx->txid,
|
2017-08-23 03:52:17 +02:00
|
|
|
tx_blockheight,
|
|
|
|
OUR_UNILATERAL, i,
|
2019-03-22 22:48:04 +01:00
|
|
|
amt,
|
2017-09-20 06:45:41 +02:00
|
|
|
THEIR_HTLC,
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
NULL, NULL,
|
2017-09-20 06:45:41 +02:00
|
|
|
remote_htlc_sigs);
|
2017-08-23 03:52:17 +02:00
|
|
|
/* BOLT #5:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* - MUST handle HTLCs offered by the remote node
|
|
|
|
* as specified in [HTLC Output Handling: Local
|
|
|
|
* Commitment, Remote Offers]
|
|
|
|
*/
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
/* Tells us which htlc to use */
|
|
|
|
which_htlc = resolve_their_htlc(out, matches, htlcs,
|
2020-04-03 03:46:18 +02:00
|
|
|
htlc_scripts,
|
|
|
|
is_replay);
|
2020-04-02 04:43:59 +02:00
|
|
|
add_amt(&their_outs, amt);
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
2018-11-22 03:17:29 +01:00
|
|
|
out->htlc = htlcs[which_htlc];
|
|
|
|
out->wscript = tal_steal(out, htlc_scripts[which_htlc]);
|
2017-09-26 23:02:47 +02:00
|
|
|
|
2017-09-20 06:45:41 +02:00
|
|
|
/* Each of these consumes one HTLC signature */
|
|
|
|
remote_htlc_sigs++;
|
|
|
|
/* We've matched this HTLC, can't do again. */
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
htlc_scripts[which_htlc] = NULL;
|
2017-09-26 23:02:47 +02:00
|
|
|
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
|
2017-09-26 23:02:47 +02:00
|
|
|
note_missing_htlcs(htlc_scripts, htlcs,
|
|
|
|
tell_if_missing, tell_immediately);
|
2020-04-03 03:46:18 +02:00
|
|
|
if (!is_replay)
|
2020-05-26 05:39:40 +02:00
|
|
|
record_chain_fees_unilateral(&tx->txid, tx_blockheight,
|
2020-04-03 23:52:35 +02:00
|
|
|
outs[0]->sat,
|
2020-04-03 03:46:18 +02:00
|
|
|
their_outs, our_outs);
|
2020-04-02 04:43:59 +02:00
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
wait_for_resolved(outs);
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
|
2017-09-26 23:02:37 +02:00
|
|
|
/* We produce individual penalty txs. It's less efficient, but avoids them
|
|
|
|
* using HTLC txs to block our penalties for long enough to pass the CSV
|
|
|
|
* delay */
|
2021-06-16 19:44:51 +02:00
|
|
|
static void steal_to_them_output(struct tracked_output *out,
|
|
|
|
u32 csv, bool is_replay)
|
2017-09-26 23:02:37 +02:00
|
|
|
{
|
|
|
|
u8 *wscript;
|
|
|
|
struct bitcoin_tx *tx;
|
2018-03-07 01:06:57 +01:00
|
|
|
enum tx_type tx_type = OUR_PENALTY_TX;
|
2017-09-26 23:02:37 +02:00
|
|
|
|
|
|
|
/* BOLT #3:
|
|
|
|
*
|
|
|
|
* If a revoked commitment transaction is published, the other party
|
|
|
|
* can spend this output immediately with the following witness:
|
|
|
|
*
|
|
|
|
* <revocation_sig> 1
|
|
|
|
*/
|
2021-06-16 19:44:51 +02:00
|
|
|
wscript = bitcoin_wscript_to_local(tmpctx, to_self_delay[REMOTE], csv,
|
2017-09-26 23:02:37 +02:00
|
|
|
&keyset->self_revocation_key,
|
|
|
|
&keyset->self_delayed_payment_key);
|
|
|
|
|
2020-09-08 05:22:41 +02:00
|
|
|
tx = tx_to_us(tmpctx, penalty_to_us, out, BITCOIN_TX_RBF_SEQUENCE, 0,
|
|
|
|
&ONE, sizeof(ONE), wscript, &tx_type, penalty_feerate);
|
2017-09-26 23:02:37 +02:00
|
|
|
|
2020-04-03 03:46:18 +02:00
|
|
|
propose_resolution(out, tx, 0, tx_type, is_replay);
|
2017-09-26 23:02:37 +02:00
|
|
|
}
|
|
|
|
|
2020-04-03 03:46:18 +02:00
|
|
|
static void steal_htlc(struct tracked_output *out, bool is_replay)
|
2017-09-26 23:02:37 +02:00
|
|
|
{
|
|
|
|
struct bitcoin_tx *tx;
|
2018-03-07 01:06:57 +01:00
|
|
|
enum tx_type tx_type = OUR_PENALTY_TX;
|
pubkey: rename PUBKEY_DER_LEN to PUBKEY_CMPR_LEN.
Pubkeys are not not actually DER encoding, but Pieter Wuille corrected
me: it's SEC 1 documented encoding.
Results from 5 runs, min-max(mean +/- stddev):
store_load_msec,vsz_kb,store_rewrite_sec,listnodes_sec,listchannels_sec,routing_sec,peer_write_all_sec
38922-39297(39180.6+/-1.3e+02),2880728,41.040000-41.160000(41.106+/-0.05),2.270000-2.530000(2.338+/-0.097),44.570000-53.980000(49.696+/-3),32.840000-33.080000(32.95+/-0.095),43.060000-44.950000(43.696+/-0.72)
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2019-04-08 08:34:05 +02:00
|
|
|
u8 der[PUBKEY_CMPR_LEN];
|
2017-09-26 23:02:37 +02:00
|
|
|
|
|
|
|
/* BOLT #3:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* If a revoked commitment transaction is published, the remote node can
|
|
|
|
* spend this output immediately with the following witness:
|
2017-09-26 23:02:37 +02:00
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* <revocation_sig> <revocationpubkey>
|
2017-09-26 23:02:37 +02:00
|
|
|
*/
|
|
|
|
pubkey_to_der(der, &keyset->self_revocation_key);
|
2020-09-08 05:22:41 +02:00
|
|
|
tx = tx_to_us(out, penalty_to_us, out, BITCOIN_TX_RBF_SEQUENCE, 0,
|
|
|
|
der, sizeof(der), out->wscript, &tx_type,
|
|
|
|
penalty_feerate);
|
2017-09-26 23:02:37 +02:00
|
|
|
|
2020-04-03 03:46:18 +02:00
|
|
|
propose_resolution(out, tx, 0, tx_type, is_replay);
|
2017-09-26 23:02:37 +02:00
|
|
|
}
|
|
|
|
|
2019-09-10 04:25:27 +02:00
|
|
|
/* Tell wallet that we have discovered a UTXO from a to-remote output,
|
|
|
|
* which it can spend with a little additional info we give here. */
|
2020-05-26 05:39:40 +02:00
|
|
|
static void tell_wallet_to_remote(const struct tx_parts *tx,
|
2019-09-10 04:25:27 +02:00
|
|
|
unsigned int outnum,
|
|
|
|
u32 tx_blockheight,
|
|
|
|
const u8 *scriptpubkey,
|
|
|
|
const struct pubkey *per_commit_point,
|
2021-06-16 20:09:32 +02:00
|
|
|
bool option_static_remotekey,
|
|
|
|
u32 csv_lock)
|
2019-09-10 04:25:27 +02:00
|
|
|
{
|
2020-05-26 05:39:40 +02:00
|
|
|
struct amount_asset asset = wally_tx_output_get_amount(tx->outputs[outnum]);
|
2019-09-26 21:07:20 +02:00
|
|
|
struct amount_sat amt;
|
|
|
|
|
|
|
|
assert(amount_asset_is_main(&asset));
|
|
|
|
amt = amount_asset_to_sat(&asset);
|
2019-09-10 04:25:27 +02:00
|
|
|
|
|
|
|
/* A NULL per_commit_point is how we indicate the pubkey doesn't need
|
|
|
|
* changing. */
|
|
|
|
if (option_static_remotekey)
|
|
|
|
per_commit_point = NULL;
|
|
|
|
|
|
|
|
wire_sync_write(REQ_FD,
|
2020-08-25 04:15:48 +02:00
|
|
|
take(towire_onchaind_add_utxo(NULL, &tx->txid, outnum,
|
2019-09-10 04:25:27 +02:00
|
|
|
per_commit_point,
|
|
|
|
amt,
|
|
|
|
tx_blockheight,
|
2021-07-02 21:54:40 +02:00
|
|
|
scriptpubkey,
|
|
|
|
csv_lock)));
|
2019-09-10 04:25:27 +02:00
|
|
|
}
|
|
|
|
|
2020-04-02 04:48:39 +02:00
|
|
|
/* When a 'cheat' transaction comes through, our accounting is
|
|
|
|
* going to be off, as it's publishing/finalizing old state.
|
|
|
|
* To compensate for this, we count *all* of the channel funds
|
|
|
|
* as ours; any subsequent handling of utxos on this tx
|
|
|
|
* will correctly mark the funds as a 'channel withdrawal'
|
|
|
|
*/
|
|
|
|
static void update_ledger_cheat(const struct bitcoin_txid *txid,
|
2020-04-03 23:52:35 +02:00
|
|
|
u32 blockheight,
|
2020-08-14 03:30:42 +02:00
|
|
|
const struct tracked_output *out)
|
2020-04-02 04:48:39 +02:00
|
|
|
{
|
|
|
|
/* how much of a difference should we update the
|
|
|
|
* channel account ledger by? */
|
|
|
|
struct amount_msat amt;
|
|
|
|
|
|
|
|
if (amount_msat_eq_sat(our_msat, out->sat))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!amount_sat_sub_msat(&amt, out->sat, our_msat))
|
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
|
|
"unable to subtract our balance %s from channel total %s",
|
|
|
|
type_to_string(tmpctx, struct amount_msat,
|
|
|
|
&our_msat),
|
|
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
|
|
&out->sat));
|
|
|
|
|
|
|
|
/* add the difference to our ledger balance */
|
2020-04-15 05:08:06 +02:00
|
|
|
send_coin_mvt(take(new_coin_journal_entry(NULL, NULL, txid,
|
|
|
|
&out->txid, out->outnum,
|
2020-04-15 05:40:28 +02:00
|
|
|
blockheight, amt, true)));
|
2020-04-02 04:48:39 +02:00
|
|
|
}
|
|
|
|
|
2021-06-16 20:09:32 +02:00
|
|
|
static void their_unilateral_local(struct tracked_output ***outs,
|
|
|
|
const struct tx_parts *tx,
|
|
|
|
u32 tx_blockheight,
|
|
|
|
size_t index,
|
|
|
|
struct amount_sat amt,
|
|
|
|
const u8 *local_scriptpubkey,
|
|
|
|
enum tx_type tx_type,
|
|
|
|
bool is_replay,
|
|
|
|
u32 csv_lock)
|
|
|
|
{
|
|
|
|
struct tracked_output *out;
|
|
|
|
/* BOLT #5:
|
|
|
|
*
|
|
|
|
* - MAY take no action in regard to the associated
|
|
|
|
* `to_remote`, which is simply a P2WPKH output to
|
|
|
|
* the *local node*.
|
|
|
|
* - Note: `to_remote` is considered *resolved* by the
|
|
|
|
* commitment transaction itself.
|
|
|
|
*/
|
|
|
|
out = new_tracked_output(outs,
|
|
|
|
&tx->txid,
|
|
|
|
tx_blockheight,
|
|
|
|
tx_type,
|
|
|
|
index, amt,
|
|
|
|
OUTPUT_TO_US,
|
|
|
|
NULL, NULL,
|
|
|
|
NULL);
|
|
|
|
ignore_output(out);
|
|
|
|
|
|
|
|
if (!is_replay)
|
|
|
|
record_channel_withdrawal(&tx->txid, tx_blockheight, out);
|
|
|
|
|
|
|
|
tell_wallet_to_remote(tx, index,
|
|
|
|
tx_blockheight,
|
|
|
|
local_scriptpubkey,
|
|
|
|
remote_per_commitment_point,
|
|
|
|
commit_num >= static_remotekey_start[REMOTE],
|
|
|
|
csv_lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-09-26 23:02:37 +02:00
|
|
|
/* BOLT #5:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* If any node tries to cheat by broadcasting an outdated commitment
|
|
|
|
* transaction (any previous commitment transaction besides the most current
|
|
|
|
* one), the other node in the channel can use its revocation private key to
|
|
|
|
* claim all the funds from the channel's original funding transaction.
|
2017-09-26 23:02:37 +02:00
|
|
|
*/
|
2020-05-26 05:39:40 +02:00
|
|
|
static void handle_their_cheat(const struct tx_parts *tx,
|
2017-09-26 23:02:37 +02:00
|
|
|
u32 tx_blockheight,
|
2018-08-17 06:16:33 +02:00
|
|
|
const struct secret *revocation_preimage,
|
2018-07-23 04:23:02 +02:00
|
|
|
const struct basepoints basepoints[NUM_SIDES],
|
2017-08-23 03:52:17 +02:00
|
|
|
const struct htlc_stub *htlcs,
|
2017-09-26 23:02:47 +02:00
|
|
|
const bool *tell_if_missing,
|
|
|
|
const bool *tell_immediately,
|
2021-06-16 20:09:32 +02:00
|
|
|
const enum side opener,
|
2020-04-03 03:46:18 +02:00
|
|
|
struct tracked_output **outs,
|
|
|
|
bool is_replay)
|
2017-08-23 03:52:17 +02:00
|
|
|
{
|
2017-09-26 23:02:37 +02:00
|
|
|
u8 **htlc_scripts;
|
2020-08-14 03:30:42 +02:00
|
|
|
u8 *remote_wscript, *script[NUM_SIDES], *anchor[NUM_SIDES];
|
2017-09-26 23:02:37 +02:00
|
|
|
struct keyset *ks;
|
2018-07-23 04:23:02 +02:00
|
|
|
struct pubkey *k;
|
2017-09-26 23:02:37 +02:00
|
|
|
size_t i;
|
2020-04-02 04:48:39 +02:00
|
|
|
/* We need to figure out what the 'chain fees'
|
|
|
|
* for this unilateral tx are */
|
|
|
|
struct amount_sat total_outs = AMOUNT_SAT(0), fee_cost;
|
|
|
|
bool amt_ok;
|
2017-09-26 23:02:37 +02:00
|
|
|
|
2018-02-23 07:23:51 +01:00
|
|
|
init_reply("Tracking their illegal close: taking all funds");
|
2019-10-04 12:27:48 +02:00
|
|
|
onchain_annotate_txin(
|
2020-05-26 05:39:40 +02:00
|
|
|
&tx->txid, 0, TX_CHANNEL_UNILATERAL | TX_CHANNEL_CHEAT | TX_THEIRS);
|
2020-04-03 23:52:35 +02:00
|
|
|
|
2020-04-03 03:46:18 +02:00
|
|
|
if (!is_replay)
|
2020-05-26 05:39:40 +02:00
|
|
|
update_ledger_cheat(&tx->txid, tx_blockheight, outs[0]);
|
2017-09-26 23:02:37 +02:00
|
|
|
|
|
|
|
/* BOLT #5:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* Once a node discovers a commitment transaction for which *it* has a
|
|
|
|
* revocation private key, the funding transaction output is *resolved*.
|
2017-09-26 23:02:37 +02:00
|
|
|
*/
|
2020-05-26 05:39:40 +02:00
|
|
|
resolved_by_other(outs[0], &tx->txid, THEIR_REVOKED_UNILATERAL);
|
2017-09-26 23:02:37 +02:00
|
|
|
|
|
|
|
/* FIXME: Types. */
|
2018-07-23 04:23:02 +02:00
|
|
|
BUILD_ASSERT(sizeof(struct secret) == sizeof(*revocation_preimage));
|
|
|
|
remote_per_commitment_secret = tal_dup(tx, struct secret,
|
|
|
|
(struct secret *)
|
|
|
|
revocation_preimage);
|
|
|
|
|
|
|
|
/* Need tmpvar for non-const. */
|
|
|
|
remote_per_commitment_point = k = tal(tx, struct pubkey);
|
|
|
|
if (!pubkey_from_secret(remote_per_commitment_secret, k))
|
2017-09-26 23:02:37 +02:00
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
2017-12-07 23:59:39 +01:00
|
|
|
"Failed derive from per_commitment_secret %s",
|
2018-07-23 04:23:02 +02:00
|
|
|
type_to_string(tmpctx, struct secret,
|
2018-07-23 04:23:02 +02:00
|
|
|
remote_per_commitment_secret));
|
2017-09-26 23:02:37 +02:00
|
|
|
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("Deriving keyset %"PRIu64
|
2017-09-26 23:02:37 +02:00
|
|
|
": per_commit_point=%s"
|
|
|
|
" self_payment_basepoint=%s"
|
|
|
|
" other_payment_basepoint=%s"
|
2017-11-15 07:16:39 +01:00
|
|
|
" self_htlc_basepoint=%s"
|
|
|
|
" other_htlc_basepoint=%s"
|
2017-09-26 23:02:37 +02:00
|
|
|
" self_delayed_basepoint=%s"
|
|
|
|
" other_revocation_basepoint=%s",
|
|
|
|
commit_num,
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2018-07-23 04:23:02 +02:00
|
|
|
remote_per_commitment_point),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2018-07-23 04:23:02 +02:00
|
|
|
&basepoints[REMOTE].payment),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2018-07-23 04:23:02 +02:00
|
|
|
&basepoints[LOCAL].payment),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2018-07-23 04:23:02 +02:00
|
|
|
&basepoints[REMOTE].htlc),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2018-07-23 04:23:02 +02:00
|
|
|
&basepoints[LOCAL].htlc),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2018-07-23 04:23:02 +02:00
|
|
|
&basepoints[REMOTE].delayed_payment),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2018-07-23 04:23:02 +02:00
|
|
|
&basepoints[LOCAL].revocation));
|
2017-09-26 23:02:37 +02:00
|
|
|
|
|
|
|
/* keyset is const, we need a non-const ptr to set it up */
|
|
|
|
keyset = ks = tal(tx, struct keyset);
|
2018-07-23 04:23:02 +02:00
|
|
|
if (!derive_keyset(remote_per_commitment_point,
|
2018-07-23 04:23:02 +02:00
|
|
|
&basepoints[REMOTE],
|
|
|
|
&basepoints[LOCAL],
|
2021-06-04 07:13:47 +02:00
|
|
|
commit_num >= static_remotekey_start[REMOTE],
|
2017-09-26 23:02:37 +02:00
|
|
|
ks))
|
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
|
|
"Deriving keyset for %"PRIu64, commit_num);
|
|
|
|
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("Deconstructing revoked unilateral tx: %"PRIu64
|
2017-09-26 23:02:37 +02:00
|
|
|
" using keyset: "
|
|
|
|
" self_revocation_key: %s"
|
|
|
|
" self_delayed_payment_key: %s"
|
|
|
|
" self_payment_key: %s"
|
2017-11-15 07:16:39 +01:00
|
|
|
" other_payment_key: %s"
|
|
|
|
" self_htlc_key: %s"
|
2019-09-10 04:25:27 +02:00
|
|
|
" other_htlc_key: %s"
|
2021-06-04 07:13:47 +02:00
|
|
|
" (static_remotekey = %"PRIu64"/%"PRIu64")",
|
2017-09-26 23:02:37 +02:00
|
|
|
commit_num,
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2017-09-26 23:02:37 +02:00
|
|
|
&keyset->self_revocation_key),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2017-09-26 23:02:37 +02:00
|
|
|
&keyset->self_delayed_payment_key),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2017-09-26 23:02:37 +02:00
|
|
|
&keyset->self_payment_key),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2017-11-15 07:16:39 +01:00
|
|
|
&keyset->other_payment_key),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2017-11-15 07:16:39 +01:00
|
|
|
&keyset->self_htlc_key),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2019-09-10 04:25:27 +02:00
|
|
|
&keyset->other_htlc_key),
|
2021-06-04 07:13:47 +02:00
|
|
|
static_remotekey_start[LOCAL],
|
|
|
|
static_remotekey_start[REMOTE]);
|
2017-09-26 23:02:37 +02:00
|
|
|
|
2021-06-16 19:44:51 +02:00
|
|
|
remote_wscript = to_self_wscript(tmpctx, to_self_delay[REMOTE],
|
|
|
|
1, keyset);
|
2017-09-26 23:02:37 +02:00
|
|
|
|
|
|
|
/* Figure out what to-them output looks like. */
|
|
|
|
script[REMOTE] = scriptpubkey_p2wsh(tmpctx, remote_wscript);
|
|
|
|
|
|
|
|
/* Figure out what direct to-us output looks like. */
|
2020-08-14 03:30:42 +02:00
|
|
|
script[LOCAL] = scriptpubkey_to_remote(tmpctx,
|
2021-06-15 22:08:44 +02:00
|
|
|
&keyset->other_payment_key, 1);
|
2017-09-26 23:02:37 +02:00
|
|
|
|
|
|
|
/* Calculate all the HTLC scripts so we can match them */
|
|
|
|
htlc_scripts = derive_htlc_scripts(htlcs, REMOTE);
|
|
|
|
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("Script to-them: %u: %s (%s)",
|
2017-09-26 23:02:37 +02:00
|
|
|
to_self_delay[REMOTE],
|
2018-03-15 05:30:38 +01:00
|
|
|
tal_hex(tmpctx, script[REMOTE]),
|
|
|
|
tal_hex(tmpctx, remote_wscript));
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("Script to-me: %s",
|
2018-03-15 05:30:38 +01:00
|
|
|
tal_hex(tmpctx, script[LOCAL]));
|
2017-09-26 23:02:37 +02:00
|
|
|
|
2020-08-14 03:30:42 +02:00
|
|
|
get_anchor_scriptpubkeys(tmpctx, anchor);
|
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
for (i = 0; i < tal_count(tx->outputs); i++) {
|
|
|
|
if (tx->outputs[i]->script_len == 0)
|
2019-09-25 14:45:34 +02:00
|
|
|
continue;
|
2020-05-26 05:39:40 +02:00
|
|
|
status_debug("Output %zu: %s",
|
|
|
|
i, tal_hexstr(tmpctx, tx->outputs[i]->script,
|
|
|
|
tx->outputs[i]->script_len));
|
2017-09-26 23:02:37 +02:00
|
|
|
}
|
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
for (i = 0; i < tal_count(tx->outputs); i++) {
|
2017-09-26 23:02:37 +02:00
|
|
|
struct tracked_output *out;
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
const size_t *matches;
|
|
|
|
size_t which_htlc;
|
2020-05-26 05:39:40 +02:00
|
|
|
struct amount_asset asset = wally_tx_output_get_amount(tx->outputs[i]);
|
2019-09-26 21:07:20 +02:00
|
|
|
struct amount_sat amt;
|
|
|
|
assert(amount_asset_is_main(&asset));
|
|
|
|
amt = amount_asset_to_sat(&asset);
|
2017-09-26 23:02:37 +02:00
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
if (chainparams->is_elements
|
|
|
|
&& tx->outputs[i]->script_len == 0) {
|
2019-05-09 18:55:42 +02:00
|
|
|
/* An empty script simply means that that this is a
|
|
|
|
* fee output. */
|
2020-05-26 05:39:40 +02:00
|
|
|
out = new_tracked_output(&outs, &tx->txid, tx_blockheight,
|
2020-04-02 04:53:40 +02:00
|
|
|
THEIR_REVOKED_UNILATERAL, i,
|
2019-05-09 18:55:42 +02:00
|
|
|
amt,
|
|
|
|
ELEMENTS_FEE,
|
|
|
|
NULL, NULL, NULL);
|
|
|
|
ignore_output(out);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2017-09-26 23:02:37 +02:00
|
|
|
if (script[LOCAL]
|
2020-05-26 05:39:40 +02:00
|
|
|
&& wally_tx_output_scripteq(tx->outputs[i],
|
|
|
|
script[LOCAL])) {
|
2021-06-16 20:09:32 +02:00
|
|
|
their_unilateral_local(&outs, tx, tx_blockheight,
|
|
|
|
i, amt, script[LOCAL],
|
|
|
|
THEIR_REVOKED_UNILATERAL,
|
|
|
|
is_replay, 1);
|
2019-02-22 16:36:09 +01:00
|
|
|
script[LOCAL] = NULL;
|
2020-04-02 04:48:39 +02:00
|
|
|
add_amt(&total_outs, amt);
|
2017-09-26 23:02:37 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (script[REMOTE]
|
2020-05-26 05:39:40 +02:00
|
|
|
&& wally_tx_output_scripteq(tx->outputs[i],
|
|
|
|
script[REMOTE])) {
|
2017-09-26 23:02:37 +02:00
|
|
|
/* BOLT #5:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* - MUST *resolve* the _remote node's main output_ by
|
|
|
|
* spending it using the revocation private key.
|
|
|
|
*/
|
2020-05-26 05:39:40 +02:00
|
|
|
out = new_tracked_output(&outs, &tx->txid, tx_blockheight,
|
2017-09-26 23:02:37 +02:00
|
|
|
THEIR_REVOKED_UNILATERAL, i,
|
2019-03-22 22:48:04 +01:00
|
|
|
amt,
|
2020-04-02 04:48:39 +02:00
|
|
|
DELAYED_CHEAT_OUTPUT_TO_THEM,
|
2017-09-26 23:02:37 +02:00
|
|
|
NULL, NULL, NULL);
|
2021-06-16 19:44:51 +02:00
|
|
|
steal_to_them_output(out, 1, is_replay);
|
2017-09-26 23:02:37 +02:00
|
|
|
script[REMOTE] = NULL;
|
2020-04-02 04:48:39 +02:00
|
|
|
add_amt(&total_outs, amt);
|
2017-09-26 23:02:37 +02:00
|
|
|
continue;
|
|
|
|
}
|
2020-08-14 03:30:42 +02:00
|
|
|
if (anchor[LOCAL]
|
|
|
|
&& wally_tx_output_scripteq(tx->outputs[i],
|
|
|
|
anchor[LOCAL])) {
|
|
|
|
/* FIXME: We should be able to spend this! */
|
|
|
|
out = new_tracked_output(&outs, &tx->txid,
|
|
|
|
tx_blockheight,
|
|
|
|
THEIR_REVOKED_UNILATERAL, i,
|
|
|
|
amt,
|
|
|
|
ANCHOR_TO_US,
|
|
|
|
NULL, NULL, NULL);
|
|
|
|
ignore_output(out);
|
|
|
|
anchor[LOCAL] = NULL;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (anchor[REMOTE]
|
|
|
|
&& wally_tx_output_scripteq(tx->outputs[i],
|
|
|
|
anchor[REMOTE])) {
|
|
|
|
out = new_tracked_output(&outs, &tx->txid,
|
|
|
|
tx_blockheight,
|
|
|
|
THEIR_REVOKED_UNILATERAL, i,
|
|
|
|
amt,
|
|
|
|
ANCHOR_TO_THEM,
|
|
|
|
NULL, NULL, NULL);
|
|
|
|
ignore_output(out);
|
|
|
|
anchor[REMOTE] = NULL;
|
|
|
|
continue;
|
|
|
|
}
|
2017-09-26 23:02:37 +02:00
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
matches = match_htlc_output(tmpctx, tx->outputs[i], htlc_scripts);
|
2021-06-04 03:53:55 +02:00
|
|
|
if (tal_count(matches) == 0) {
|
2021-06-16 20:09:32 +02:00
|
|
|
bool found = false;
|
|
|
|
if (opener == REMOTE && script[LOCAL]) {
|
|
|
|
status_debug("Grinding for commitment to_remote"
|
|
|
|
" (ours)");
|
|
|
|
/* We already tried `1` */
|
|
|
|
for (size_t csv = 2;
|
|
|
|
csv <= LEASE_RATE_DURATION;
|
|
|
|
csv++) {
|
|
|
|
script[LOCAL]
|
|
|
|
= scriptpubkey_to_remote(tmpctx,
|
|
|
|
&keyset->other_payment_key,
|
|
|
|
csv);
|
|
|
|
if (!wally_tx_output_scripteq(
|
|
|
|
tx->outputs[i],
|
|
|
|
script[LOCAL]))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
their_unilateral_local(&outs, tx,
|
|
|
|
tx_blockheight,
|
|
|
|
i, amt,
|
|
|
|
script[LOCAL],
|
|
|
|
THEIR_REVOKED_UNILATERAL,
|
|
|
|
is_replay,
|
|
|
|
csv);
|
|
|
|
script[LOCAL] = NULL;
|
|
|
|
add_amt(&total_outs, amt);
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else if (opener == LOCAL && script[REMOTE]) {
|
|
|
|
status_debug("Grinding for commitment to_local"
|
|
|
|
" (theirs)");
|
|
|
|
for (size_t csv = 2;
|
|
|
|
csv <= LEASE_RATE_DURATION;
|
|
|
|
csv++) {
|
|
|
|
remote_wscript
|
|
|
|
= to_self_wscript(tmpctx,
|
|
|
|
to_self_delay[REMOTE],
|
|
|
|
csv, keyset);
|
|
|
|
script[REMOTE]
|
|
|
|
= scriptpubkey_p2wsh(tmpctx,
|
|
|
|
remote_wscript);
|
|
|
|
|
|
|
|
|
|
|
|
if (!wally_tx_output_scripteq(tx->outputs[i], script[REMOTE]))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
out = new_tracked_output(&outs, &tx->txid, tx_blockheight,
|
|
|
|
THEIR_REVOKED_UNILATERAL, i,
|
|
|
|
amt,
|
|
|
|
DELAYED_CHEAT_OUTPUT_TO_THEM,
|
|
|
|
NULL, NULL, NULL);
|
|
|
|
steal_to_them_output(out, csv,
|
|
|
|
is_replay);
|
|
|
|
script[REMOTE] = NULL;
|
|
|
|
add_amt(&total_outs, amt);
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!found)
|
|
|
|
status_broken("Could not find resolution"
|
|
|
|
" for output %zu: did"
|
|
|
|
" *we* cheat?", i);
|
2021-06-04 03:53:55 +02:00
|
|
|
continue;
|
|
|
|
}
|
2017-09-26 23:02:37 +02:00
|
|
|
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
/* In this case, we don't care which HTLC we choose; so pick
|
|
|
|
first one */
|
|
|
|
which_htlc = matches[0];
|
|
|
|
if (matches_direction(matches, htlcs) == LOCAL) {
|
2017-09-26 23:02:37 +02:00
|
|
|
/* BOLT #5:
|
|
|
|
*
|
2019-01-14 03:26:25 +01:00
|
|
|
* - MUST *resolve* the _local node's offered HTLCs_ in one of three ways:
|
|
|
|
* * spend the *commitment tx* using the payment revocation private key.
|
|
|
|
* * spend the *commitment tx* once the HTLC timeout has passed.
|
|
|
|
* * spend the *HTLC-success tx*, if the remote node has published it.
|
2017-09-26 23:02:37 +02:00
|
|
|
*/
|
2020-05-26 05:39:40 +02:00
|
|
|
out = new_tracked_output(&outs, &tx->txid,
|
2017-09-26 23:02:37 +02:00
|
|
|
tx_blockheight,
|
|
|
|
THEIR_REVOKED_UNILATERAL, i,
|
2019-03-22 22:48:04 +01:00
|
|
|
amt,
|
2017-09-26 23:02:37 +02:00
|
|
|
OUR_HTLC,
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
&htlcs[which_htlc],
|
|
|
|
htlc_scripts[which_htlc],
|
2017-09-26 23:02:37 +02:00
|
|
|
NULL);
|
2020-04-03 03:46:18 +02:00
|
|
|
steal_htlc(out, is_replay);
|
2020-04-02 04:48:39 +02:00
|
|
|
add_amt(&total_outs, amt);
|
2017-09-26 23:02:37 +02:00
|
|
|
} else {
|
2020-05-26 05:39:40 +02:00
|
|
|
out = new_tracked_output(&outs, &tx->txid,
|
2017-09-26 23:02:37 +02:00
|
|
|
tx_blockheight,
|
|
|
|
THEIR_REVOKED_UNILATERAL, i,
|
2019-03-22 22:48:04 +01:00
|
|
|
amt,
|
2017-09-26 23:02:37 +02:00
|
|
|
THEIR_HTLC,
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
&htlcs[which_htlc],
|
|
|
|
htlc_scripts[which_htlc],
|
2017-09-26 23:02:37 +02:00
|
|
|
NULL);
|
|
|
|
/* BOLT #5:
|
|
|
|
*
|
2019-01-14 03:26:25 +01:00
|
|
|
* - MUST *resolve* the _remote node's offered HTLCs_ in one of three ways:
|
|
|
|
* * spend the *commitment tx* using the payment revocation private key.
|
|
|
|
* * spend the *commitment tx* using the payment preimage (if known).
|
|
|
|
* * spend the *HTLC-timeout tx*, if the remote node has published it.
|
2017-09-26 23:02:37 +02:00
|
|
|
*/
|
2020-04-03 03:46:18 +02:00
|
|
|
steal_htlc(out, is_replay);
|
2020-04-02 04:48:39 +02:00
|
|
|
add_amt(&total_outs, amt);
|
2017-09-26 23:02:37 +02:00
|
|
|
}
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
htlc_scripts[which_htlc] = NULL;
|
2017-09-26 23:02:37 +02:00
|
|
|
}
|
|
|
|
|
2017-09-26 23:02:47 +02:00
|
|
|
note_missing_htlcs(htlc_scripts, htlcs,
|
|
|
|
tell_if_missing, tell_immediately);
|
2020-04-02 04:48:39 +02:00
|
|
|
|
|
|
|
/* Record the fee cost for this tx, deducting it from channel balance */
|
|
|
|
amt_ok = amount_sat_sub(&fee_cost, outs[0]->sat, total_outs);
|
|
|
|
assert(amt_ok);
|
|
|
|
status_debug("recording chain fees for their cheat %s",
|
|
|
|
type_to_string(tmpctx, struct amount_sat, &fee_cost));
|
2020-04-03 03:46:18 +02:00
|
|
|
|
|
|
|
if (!is_replay)
|
2020-05-26 05:39:40 +02:00
|
|
|
update_ledger_chain_fees(&tx->txid, tx_blockheight, fee_cost);
|
2020-04-02 04:48:39 +02:00
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
wait_for_resolved(outs);
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
static void handle_their_unilateral(const struct tx_parts *tx,
|
2017-08-23 03:52:17 +02:00
|
|
|
u32 tx_blockheight,
|
2018-07-23 04:23:02 +02:00
|
|
|
const struct pubkey *this_remote_per_commitment_point,
|
2018-07-23 04:23:02 +02:00
|
|
|
const struct basepoints basepoints[NUM_SIDES],
|
2017-08-23 03:52:17 +02:00
|
|
|
const struct htlc_stub *htlcs,
|
2017-09-26 23:02:47 +02:00
|
|
|
const bool *tell_if_missing,
|
|
|
|
const bool *tell_immediately,
|
2021-06-16 20:09:32 +02:00
|
|
|
const enum side opener,
|
2020-04-03 03:46:18 +02:00
|
|
|
struct tracked_output **outs,
|
|
|
|
bool is_replay)
|
2017-08-23 03:52:17 +02:00
|
|
|
{
|
|
|
|
u8 **htlc_scripts;
|
2020-08-14 03:30:42 +02:00
|
|
|
u8 *remote_wscript, *script[NUM_SIDES], *anchor[NUM_SIDES];
|
2017-09-16 01:36:06 +02:00
|
|
|
struct keyset *ks;
|
2017-08-23 03:52:17 +02:00
|
|
|
size_t i;
|
2020-04-02 04:43:59 +02:00
|
|
|
struct amount_sat their_outs = AMOUNT_SAT(0), our_outs = AMOUNT_SAT(0);
|
2017-08-23 03:52:17 +02:00
|
|
|
|
2018-02-23 07:23:51 +01:00
|
|
|
init_reply("Tracking their unilateral close");
|
2020-05-26 05:39:40 +02:00
|
|
|
onchain_annotate_txin(&tx->txid, 0, TX_CHANNEL_UNILATERAL | TX_THEIRS);
|
2017-08-23 03:52:17 +02:00
|
|
|
|
2018-07-23 04:23:02 +02:00
|
|
|
/* HSM can't derive this. */
|
|
|
|
remote_per_commitment_point = this_remote_per_commitment_point;
|
|
|
|
|
2017-08-23 03:52:17 +02:00
|
|
|
/* BOLT #5:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* # Unilateral Close Handling: Remote Commitment Transaction
|
2017-08-23 03:52:17 +02:00
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* The *remote node's* commitment transaction *resolves* the funding
|
|
|
|
* transaction output.
|
|
|
|
*
|
|
|
|
* There are no delays constraining node behavior in this case, so
|
|
|
|
* it's simpler for a node to handle than the case in which it
|
|
|
|
* discovers its local commitment transaction (see [Unilateral Close
|
|
|
|
* Handling: Local Commitment Transaction]
|
2017-08-23 03:52:17 +02:00
|
|
|
*/
|
2020-05-26 05:39:40 +02:00
|
|
|
resolved_by_other(outs[0], &tx->txid, THEIR_UNILATERAL);
|
2017-08-23 03:52:17 +02:00
|
|
|
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("Deriving keyset %"PRIu64
|
2017-08-23 03:52:17 +02:00
|
|
|
": per_commit_point=%s"
|
|
|
|
" self_payment_basepoint=%s"
|
|
|
|
" other_payment_basepoint=%s"
|
2017-11-15 07:16:39 +01:00
|
|
|
" self_htlc_basepoint=%s"
|
|
|
|
" other_htlc_basepoint=%s"
|
2017-08-23 03:52:17 +02:00
|
|
|
" self_delayed_basepoint=%s"
|
|
|
|
" other_revocation_basepoint=%s",
|
|
|
|
commit_num,
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2017-08-23 03:52:17 +02:00
|
|
|
remote_per_commitment_point),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2018-07-23 04:23:02 +02:00
|
|
|
&basepoints[REMOTE].payment),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2018-07-23 04:23:02 +02:00
|
|
|
&basepoints[LOCAL].payment),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2018-07-23 04:23:02 +02:00
|
|
|
&basepoints[REMOTE].htlc),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2018-07-23 04:23:02 +02:00
|
|
|
&basepoints[LOCAL].htlc),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2018-07-23 04:23:02 +02:00
|
|
|
&basepoints[REMOTE].delayed_payment),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2018-07-23 04:23:02 +02:00
|
|
|
&basepoints[LOCAL].revocation));
|
2017-08-23 03:52:17 +02:00
|
|
|
|
2017-09-16 01:36:06 +02:00
|
|
|
/* keyset is const, we need a non-const ptr to set it up */
|
|
|
|
keyset = ks = tal(tx, struct keyset);
|
2017-08-23 03:52:17 +02:00
|
|
|
if (!derive_keyset(remote_per_commitment_point,
|
2018-07-23 04:23:02 +02:00
|
|
|
&basepoints[REMOTE],
|
|
|
|
&basepoints[LOCAL],
|
2021-06-04 07:13:47 +02:00
|
|
|
commit_num >= static_remotekey_start[REMOTE],
|
2017-09-16 01:36:06 +02:00
|
|
|
ks))
|
2017-09-12 06:55:52 +02:00
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
2017-08-23 03:52:17 +02:00
|
|
|
"Deriving keyset for %"PRIu64, commit_num);
|
|
|
|
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("Deconstructing unilateral tx: %"PRIu64
|
2017-08-23 03:52:17 +02:00
|
|
|
" using keyset: "
|
|
|
|
" self_revocation_key: %s"
|
|
|
|
" self_delayed_payment_key: %s"
|
|
|
|
" self_payment_key: %s"
|
2017-11-15 07:16:39 +01:00
|
|
|
" other_payment_key: %s"
|
|
|
|
" self_htlc_key: %s"
|
|
|
|
" other_htlc_key: %s",
|
2017-08-23 03:52:17 +02:00
|
|
|
commit_num,
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2017-09-16 01:36:06 +02:00
|
|
|
&keyset->self_revocation_key),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2017-09-16 01:36:06 +02:00
|
|
|
&keyset->self_delayed_payment_key),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2017-09-16 01:36:06 +02:00
|
|
|
&keyset->self_payment_key),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2017-11-15 07:16:39 +01:00
|
|
|
&keyset->other_payment_key),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2017-11-15 07:16:39 +01:00
|
|
|
&keyset->self_htlc_key),
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2017-11-15 07:16:39 +01:00
|
|
|
&keyset->other_htlc_key));
|
2017-08-23 03:52:17 +02:00
|
|
|
|
|
|
|
/* Calculate all the HTLC scripts so we can match them */
|
2017-09-16 01:36:06 +02:00
|
|
|
htlc_scripts = derive_htlc_scripts(htlcs, REMOTE);
|
2017-08-23 03:52:17 +02:00
|
|
|
|
2020-08-14 03:30:42 +02:00
|
|
|
get_anchor_scriptpubkeys(tmpctx, anchor);
|
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
for (i = 0; i < tal_count(tx->outputs); i++) {
|
|
|
|
if (tx->outputs[i]->script_len == 0)
|
2019-09-25 14:45:34 +02:00
|
|
|
continue;
|
2020-05-26 05:39:40 +02:00
|
|
|
status_debug("Output %zu: %s",
|
|
|
|
i, tal_hexstr(tmpctx, tx->outputs[i]->script,
|
|
|
|
tx->outputs[i]->script_len));
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
|
2021-06-16 20:09:32 +02:00
|
|
|
remote_wscript = to_self_wscript(tmpctx, to_self_delay[REMOTE],
|
|
|
|
1, keyset);
|
|
|
|
script[REMOTE] = scriptpubkey_p2wsh(tmpctx, remote_wscript);
|
|
|
|
|
|
|
|
script[LOCAL] = scriptpubkey_to_remote(tmpctx,
|
|
|
|
&keyset->other_payment_key,
|
|
|
|
1);
|
|
|
|
|
|
|
|
status_debug("Script to-them: %u: %s (%s)",
|
|
|
|
to_self_delay[REMOTE],
|
|
|
|
tal_hex(tmpctx, script[REMOTE]),
|
|
|
|
tal_hex(tmpctx, remote_wscript));
|
|
|
|
status_debug("Script to-me: %s",
|
|
|
|
tal_hex(tmpctx, script[LOCAL]));
|
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
for (i = 0; i < tal_count(tx->outputs); i++) {
|
2017-08-23 03:52:17 +02:00
|
|
|
struct tracked_output *out;
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
const size_t *matches;
|
|
|
|
size_t which_htlc;
|
2020-05-26 05:39:40 +02:00
|
|
|
struct amount_asset asset = wally_tx_output_get_amount(tx->outputs[i]);
|
2019-09-26 21:07:20 +02:00
|
|
|
struct amount_sat amt;
|
|
|
|
assert(amount_asset_is_main(&asset));
|
|
|
|
amt = amount_asset_to_sat(&asset);
|
2017-08-23 03:52:17 +02:00
|
|
|
|
2019-09-26 00:42:26 +02:00
|
|
|
if (chainparams->is_elements &&
|
2020-05-26 05:39:40 +02:00
|
|
|
tx->outputs[i]->script_len == 0) {
|
2019-05-09 18:55:42 +02:00
|
|
|
/* An empty script simply means that that this is a
|
|
|
|
* fee output. */
|
2020-05-26 05:39:40 +02:00
|
|
|
out = new_tracked_output(&outs, &tx->txid, tx_blockheight,
|
2020-04-02 04:53:40 +02:00
|
|
|
THEIR_UNILATERAL, i,
|
2019-05-09 18:55:42 +02:00
|
|
|
amt,
|
|
|
|
ELEMENTS_FEE,
|
|
|
|
NULL, NULL, NULL);
|
|
|
|
ignore_output(out);
|
|
|
|
continue;
|
2020-05-26 05:39:40 +02:00
|
|
|
} else if (script[LOCAL]
|
|
|
|
&& wally_tx_output_scripteq(tx->outputs[i],
|
|
|
|
script[LOCAL])) {
|
2021-06-16 20:09:32 +02:00
|
|
|
their_unilateral_local(&outs, tx, tx_blockheight,
|
|
|
|
i, amt, script[LOCAL],
|
|
|
|
THEIR_UNILATERAL,
|
|
|
|
is_replay, 1);
|
2017-12-19 17:09:52 +01:00
|
|
|
|
2019-02-22 16:36:09 +01:00
|
|
|
script[LOCAL] = NULL;
|
2020-04-02 04:43:59 +02:00
|
|
|
add_amt(&our_outs, amt);
|
2017-08-23 03:52:17 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (script[REMOTE]
|
2020-05-26 05:39:40 +02:00
|
|
|
&& wally_tx_output_scripteq(tx->outputs[i],
|
|
|
|
script[REMOTE])) {
|
2017-08-23 03:52:17 +02:00
|
|
|
/* BOLT #5:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* - MAY take no action in regard to the associated
|
|
|
|
* `to_local`, which is a payment output to the *remote
|
|
|
|
* node*.
|
|
|
|
* - Note: `to_local` is considered *resolved* by the
|
|
|
|
* commitment transaction itself.
|
|
|
|
*/
|
2020-05-26 05:39:40 +02:00
|
|
|
out = new_tracked_output(&outs, &tx->txid, tx_blockheight,
|
2017-08-23 03:52:17 +02:00
|
|
|
THEIR_UNILATERAL, i,
|
2019-03-22 22:48:04 +01:00
|
|
|
amt,
|
2017-09-20 06:45:41 +02:00
|
|
|
DELAYED_OUTPUT_TO_THEM,
|
|
|
|
NULL, NULL, NULL);
|
2017-08-23 03:52:17 +02:00
|
|
|
ignore_output(out);
|
2020-04-02 04:43:59 +02:00
|
|
|
add_amt(&their_outs, amt);
|
2017-08-23 03:52:17 +02:00
|
|
|
continue;
|
|
|
|
}
|
2020-08-14 03:30:42 +02:00
|
|
|
if (anchor[LOCAL]
|
|
|
|
&& wally_tx_output_scripteq(tx->outputs[i],
|
|
|
|
anchor[LOCAL])) {
|
|
|
|
/* FIXME: We should be able to spend this! */
|
|
|
|
out = new_tracked_output(&outs, &tx->txid,
|
|
|
|
tx_blockheight,
|
|
|
|
THEIR_UNILATERAL, i,
|
|
|
|
amt,
|
|
|
|
ANCHOR_TO_US,
|
|
|
|
NULL, NULL, NULL);
|
|
|
|
ignore_output(out);
|
|
|
|
anchor[LOCAL] = NULL;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (anchor[REMOTE]
|
|
|
|
&& wally_tx_output_scripteq(tx->outputs[i],
|
|
|
|
anchor[REMOTE])) {
|
|
|
|
out = new_tracked_output(&outs, &tx->txid,
|
|
|
|
tx_blockheight,
|
|
|
|
THEIR_UNILATERAL, i,
|
|
|
|
amt,
|
|
|
|
ANCHOR_TO_THEM,
|
|
|
|
NULL, NULL, NULL);
|
|
|
|
ignore_output(out);
|
|
|
|
anchor[REMOTE] = NULL;
|
|
|
|
continue;
|
|
|
|
}
|
2017-08-23 03:52:17 +02:00
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
matches = match_htlc_output(tmpctx, tx->outputs[i], htlc_scripts);
|
2021-06-16 20:09:32 +02:00
|
|
|
if (tal_count(matches) == 0) {
|
|
|
|
bool found = false;
|
|
|
|
|
|
|
|
/* We need to hunt for it (option_will_fund?) */
|
|
|
|
if (opener == REMOTE && script[LOCAL]) {
|
|
|
|
status_debug("Grinding for commitment to_remote"
|
|
|
|
" (ours)");
|
|
|
|
/* We already tried `1` */
|
|
|
|
for (size_t csv = 2;
|
|
|
|
csv <= LEASE_RATE_DURATION;
|
|
|
|
csv++) {
|
|
|
|
script[LOCAL]
|
|
|
|
= scriptpubkey_to_remote(tmpctx,
|
|
|
|
&keyset->other_payment_key,
|
|
|
|
csv);
|
|
|
|
if (!wally_tx_output_scripteq(
|
|
|
|
tx->outputs[i],
|
|
|
|
script[LOCAL]))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
their_unilateral_local(&outs, tx,
|
|
|
|
tx_blockheight,
|
|
|
|
i, amt,
|
|
|
|
script[LOCAL],
|
|
|
|
THEIR_UNILATERAL,
|
|
|
|
is_replay, csv);
|
|
|
|
script[LOCAL] = NULL;
|
|
|
|
add_amt(&our_outs, amt);
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else if (opener == LOCAL && script[REMOTE]) {
|
|
|
|
status_debug("Grinding for commitment to_local"
|
|
|
|
" (theirs)");
|
|
|
|
/* We already tried `1` */
|
|
|
|
for (size_t csv = 2;
|
|
|
|
csv <= LEASE_RATE_DURATION;
|
|
|
|
csv++) {
|
|
|
|
remote_wscript
|
|
|
|
= to_self_wscript(tmpctx,
|
|
|
|
to_self_delay[REMOTE],
|
|
|
|
csv, keyset);
|
|
|
|
script[REMOTE]
|
|
|
|
= scriptpubkey_p2wsh(tmpctx,
|
|
|
|
remote_wscript);
|
|
|
|
|
|
|
|
|
|
|
|
if (!wally_tx_output_scripteq(tx->outputs[i], script[REMOTE]))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
out = new_tracked_output(&outs, &tx->txid, tx_blockheight,
|
|
|
|
THEIR_UNILATERAL, i,
|
|
|
|
amt,
|
|
|
|
DELAYED_OUTPUT_TO_THEM,
|
|
|
|
NULL, NULL, NULL);
|
|
|
|
ignore_output(out);
|
|
|
|
add_amt(&their_outs, amt);
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (found)
|
|
|
|
continue;
|
|
|
|
|
2017-09-12 06:55:52 +02:00
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
2017-08-23 03:52:17 +02:00
|
|
|
"Could not find resolution for output %zu",
|
|
|
|
i);
|
2021-06-16 20:09:32 +02:00
|
|
|
}
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
|
|
|
|
if (matches_direction(matches, htlcs) == LOCAL) {
|
2017-08-23 03:52:17 +02:00
|
|
|
/* BOLT #5:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* - MUST handle HTLCs offered by itself as specified in
|
|
|
|
* [HTLC Output Handling: Remote Commitment,
|
|
|
|
* Local Offers]
|
|
|
|
*/
|
2020-05-26 05:39:40 +02:00
|
|
|
out = new_tracked_output(&outs, &tx->txid,
|
2017-08-23 03:52:17 +02:00
|
|
|
tx_blockheight,
|
|
|
|
THEIR_UNILATERAL, i,
|
2019-03-22 22:48:04 +01:00
|
|
|
amt,
|
2017-09-20 06:45:41 +02:00
|
|
|
OUR_HTLC,
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
NULL, NULL,
|
2017-09-20 06:45:41 +02:00
|
|
|
NULL);
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
which_htlc = resolve_our_htlc_theircommit(out,
|
|
|
|
matches,
|
|
|
|
htlcs,
|
2020-04-03 03:46:18 +02:00
|
|
|
htlc_scripts,
|
|
|
|
is_replay);
|
2020-04-02 04:43:59 +02:00
|
|
|
add_amt(&our_outs, amt);
|
2017-08-23 03:52:17 +02:00
|
|
|
} else {
|
2020-05-26 05:39:40 +02:00
|
|
|
out = new_tracked_output(&outs, &tx->txid,
|
2017-08-23 03:52:17 +02:00
|
|
|
tx_blockheight,
|
|
|
|
THEIR_UNILATERAL, i,
|
2019-03-22 22:48:04 +01:00
|
|
|
amt,
|
2017-09-20 06:45:41 +02:00
|
|
|
THEIR_HTLC,
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
NULL, NULL,
|
2017-09-20 06:45:41 +02:00
|
|
|
NULL);
|
2017-08-23 03:52:17 +02:00
|
|
|
/* BOLT #5:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* - MUST handle HTLCs offered by the remote node as
|
|
|
|
* specified in [HTLC Output Handling: Remote
|
|
|
|
* Commitment, Remote Offers]
|
|
|
|
*/
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
which_htlc = resolve_their_htlc(out, matches, htlcs,
|
2020-04-03 03:46:18 +02:00
|
|
|
htlc_scripts, is_replay);
|
2020-04-02 04:43:59 +02:00
|
|
|
add_amt(&their_outs, amt);
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
2018-11-22 03:17:29 +01:00
|
|
|
out->htlc = htlcs[which_htlc];
|
|
|
|
out->wscript = tal_steal(out, htlc_scripts[which_htlc]);
|
onchaind: allow multiple candidate HTLCs for output match
When we have multiple HTLCs with the same preimage and the same CLTV,
it doesn't matter what order we treat them (they're literally
identical). But when we offer HTLCs with the same preimage but
different CLTVs, the commitment tx outputs look identical, but the
HTLC txs are different: if we simply take the first HTLC which matches
(and that's not the right one), the HTLC signature we got from them
won't match. As we rely on the signature matching to detect the fee
paid, we get:
onchaind: STATUS_FAIL_INTERNAL_ERROR: grind_fee failed
So we alter match_htlc_output() to return an array of all matching
HTLC indices, which can have more than one entry for offered HTLCs.
If it's our commitment, we loop through until one of the HTLC
signatures matches. If it's their commitment, we choose the HTLC with
the largest CLTV: we're going to ignore it once that hits anyway, so
this is the most conservative approach. If it's a penalty, it doesn't
matter since we steal all HTLC outputs the same independent of CLTV.
For accepted HTLCs, the CLTV value is encoded in the witness script,
so this confusion isn't possible. We nonetheless assert that the
CLTVs all match in that case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-10-23 11:40:23 +02:00
|
|
|
htlc_scripts[which_htlc] = NULL;
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
|
2017-09-26 23:02:47 +02:00
|
|
|
note_missing_htlcs(htlc_scripts, htlcs,
|
|
|
|
tell_if_missing, tell_immediately);
|
2020-04-03 03:46:18 +02:00
|
|
|
|
|
|
|
if (!is_replay)
|
2020-05-26 05:39:40 +02:00
|
|
|
record_chain_fees_unilateral(&tx->txid, tx_blockheight,
|
2020-04-03 23:52:35 +02:00
|
|
|
outs[0]->sat,
|
2020-04-03 03:46:18 +02:00
|
|
|
their_outs, our_outs);
|
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
wait_for_resolved(outs);
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
|
2020-04-02 04:41:19 +02:00
|
|
|
static void update_ledger_unknown(const struct bitcoin_txid *txid,
|
2020-04-03 23:52:35 +02:00
|
|
|
u32 blockheight,
|
2020-04-02 04:41:19 +02:00
|
|
|
struct amount_sat amt_salvaged)
|
|
|
|
{
|
|
|
|
/* ideally, we'd be able to capture the loss to fees (if we funded
|
|
|
|
* the channel) here separately, but given that we don't know the htlc
|
|
|
|
* set (and thus which outputs are trimmed), this is difficult.
|
|
|
|
*
|
|
|
|
* instead, we count the difference between any recoverable output
|
|
|
|
* and our current channel balance as a loss (or gain) */
|
|
|
|
bool is_credit;
|
|
|
|
struct amount_msat diff;
|
|
|
|
|
|
|
|
/* we do nothing if the amount withdrawn via 'salvage' is
|
|
|
|
* the same as our channel balance */
|
|
|
|
if (amount_msat_eq_sat(our_msat, amt_salvaged))
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* if we've withdrawn *less* in salvage than we have on the books
|
|
|
|
* as being ours, we record the difference as a debit */
|
|
|
|
if (!amount_msat_sub_sat(&diff, our_msat, amt_salvaged)) {
|
|
|
|
is_credit = false;
|
|
|
|
if (!amount_sat_sub_msat(&diff, amt_salvaged, our_msat))
|
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
|
|
"overflow subtracting %s from %s",
|
|
|
|
type_to_string(tmpctx, struct amount_msat,
|
|
|
|
&our_msat),
|
|
|
|
type_to_string(tmpctx, struct amount_sat,
|
|
|
|
&amt_salvaged));
|
|
|
|
} else
|
|
|
|
is_credit = true;
|
|
|
|
|
2020-04-15 05:08:06 +02:00
|
|
|
send_coin_mvt(take(new_coin_journal_entry(NULL, NULL, txid, NULL, 0,
|
2020-04-15 05:40:28 +02:00
|
|
|
blockheight, diff, is_credit)));
|
2020-04-02 04:41:19 +02:00
|
|
|
}
|
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
static void handle_unknown_commitment(const struct tx_parts *tx,
|
2018-08-17 07:06:36 +02:00
|
|
|
u32 tx_blockheight,
|
|
|
|
const struct pubkey *possible_remote_per_commitment_point,
|
|
|
|
const struct basepoints basepoints[NUM_SIDES],
|
|
|
|
const struct htlc_stub *htlcs,
|
|
|
|
const bool *tell_if_missing,
|
2020-04-03 03:46:18 +02:00
|
|
|
struct tracked_output **outs,
|
|
|
|
bool is_replay)
|
2018-08-17 07:06:36 +02:00
|
|
|
{
|
|
|
|
int to_us_output = -1;
|
2021-06-04 03:53:43 +02:00
|
|
|
/* We have two possible local scripts, depending on options */
|
|
|
|
u8 *local_scripts[2];
|
2020-04-02 04:41:19 +02:00
|
|
|
struct amount_sat amt_salvaged = AMOUNT_SAT(0);
|
2018-08-17 07:06:36 +02:00
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
onchain_annotate_txin(&tx->txid, 0, TX_CHANNEL_UNILATERAL | TX_THEIRS);
|
2019-05-28 18:09:30 +02:00
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
resolved_by_other(outs[0], &tx->txid, UNKNOWN_UNILATERAL);
|
2018-08-17 07:06:36 +02:00
|
|
|
|
2021-06-04 03:53:43 +02:00
|
|
|
/* This is the not-option_static_remotekey case, if we got a hint
|
|
|
|
* from them about the per-commitment point */
|
|
|
|
if (possible_remote_per_commitment_point) {
|
2019-09-10 04:25:27 +02:00
|
|
|
struct keyset *ks = tal(tmpctx, struct keyset);
|
|
|
|
if (!derive_keyset(possible_remote_per_commitment_point,
|
|
|
|
&basepoints[REMOTE],
|
|
|
|
&basepoints[LOCAL],
|
2021-06-04 03:53:43 +02:00
|
|
|
false,
|
2019-09-10 04:25:27 +02:00
|
|
|
ks))
|
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
|
|
"Deriving keyset for possible_remote_per_commitment_point %s",
|
|
|
|
type_to_string(tmpctx, struct pubkey,
|
|
|
|
possible_remote_per_commitment_point));
|
|
|
|
|
2021-06-04 03:53:43 +02:00
|
|
|
local_scripts[0] = scriptpubkey_p2wpkh(tmpctx,
|
|
|
|
&ks->other_payment_key);
|
2019-09-10 04:25:27 +02:00
|
|
|
} else {
|
2021-06-04 03:53:43 +02:00
|
|
|
local_scripts[0] = NULL;
|
2019-09-10 04:25:27 +02:00
|
|
|
}
|
2018-08-17 07:06:36 +02:00
|
|
|
|
2021-06-16 20:09:32 +02:00
|
|
|
/* For option_will_fund, we need to figure out what CSV lock was used */
|
|
|
|
for (size_t csv = 1; csv <= LEASE_RATE_DURATION; csv++) {
|
2021-06-04 03:53:43 +02:00
|
|
|
|
2021-06-16 20:09:32 +02:00
|
|
|
/* Other possible local script is for option_static_remotekey */
|
|
|
|
local_scripts[1] = scriptpubkey_to_remote(tmpctx,
|
|
|
|
&basepoints[LOCAL].payment,
|
|
|
|
csv);
|
2021-06-04 03:53:43 +02:00
|
|
|
|
2021-06-16 20:09:32 +02:00
|
|
|
for (size_t i = 0; i < tal_count(tx->outputs); i++) {
|
|
|
|
struct tracked_output *out;
|
|
|
|
struct amount_asset asset = wally_tx_output_get_amount(tx->outputs[i]);
|
|
|
|
struct amount_sat amt;
|
|
|
|
int which_script;
|
2018-08-17 07:06:36 +02:00
|
|
|
|
2021-06-16 20:09:32 +02:00
|
|
|
assert(amount_asset_is_main(&asset));
|
|
|
|
amt = amount_asset_to_sat(&asset);
|
|
|
|
|
|
|
|
/* Elements can have empty output scripts (fee output) */
|
|
|
|
if (local_scripts[0]
|
|
|
|
&& wally_tx_output_scripteq(tx->outputs[i], local_scripts[0]))
|
|
|
|
which_script = 0;
|
|
|
|
else if (local_scripts[1]
|
|
|
|
&& wally_tx_output_scripteq(tx->outputs[i],
|
|
|
|
local_scripts[1]))
|
|
|
|
which_script = 1;
|
|
|
|
else
|
|
|
|
continue;
|
2020-04-03 03:46:18 +02:00
|
|
|
|
2021-06-16 20:09:32 +02:00
|
|
|
/* BOLT #5:
|
|
|
|
*
|
|
|
|
* - MAY take no action in regard to the associated
|
|
|
|
* `to_remote`, which is simply a P2WPKH output to
|
|
|
|
* the *local node*.
|
|
|
|
* - Note: `to_remote` is considered *resolved* by the
|
|
|
|
* commitment transaction itself.
|
|
|
|
*/
|
|
|
|
out = new_tracked_output(&outs, &tx->txid, tx_blockheight,
|
|
|
|
UNKNOWN_UNILATERAL,
|
|
|
|
i, amt,
|
|
|
|
OUTPUT_TO_US, NULL, NULL, NULL);
|
|
|
|
ignore_output(out);
|
2020-04-03 03:46:18 +02:00
|
|
|
|
2021-06-16 20:09:32 +02:00
|
|
|
if (!is_replay)
|
|
|
|
record_channel_withdrawal(&tx->txid, tx_blockheight, out);
|
2018-08-17 07:06:36 +02:00
|
|
|
|
2021-06-16 20:09:32 +02:00
|
|
|
add_amt(&amt_salvaged, amt);
|
2021-06-04 03:53:43 +02:00
|
|
|
|
2021-06-16 20:09:32 +02:00
|
|
|
tell_wallet_to_remote(tx, i,
|
|
|
|
tx_blockheight,
|
|
|
|
local_scripts[which_script],
|
|
|
|
possible_remote_per_commitment_point,
|
|
|
|
which_script == 1,
|
|
|
|
csv);
|
|
|
|
local_scripts[0] = local_scripts[1] = NULL;
|
|
|
|
to_us_output = i;
|
|
|
|
goto script_found;
|
|
|
|
}
|
2018-08-17 07:06:36 +02:00
|
|
|
}
|
|
|
|
|
2021-06-16 20:09:32 +02:00
|
|
|
script_found:
|
2018-08-17 07:06:36 +02:00
|
|
|
if (to_us_output == -1) {
|
|
|
|
status_broken("FUNDS LOST. Unknown commitment #%"PRIu64"!",
|
|
|
|
commit_num);
|
|
|
|
init_reply("ERROR: FUNDS LOST. Unknown commitment!");
|
|
|
|
} else {
|
|
|
|
status_broken("ERROR: Unknown commitment #%"PRIu64
|
|
|
|
", recovering our funds!",
|
|
|
|
commit_num);
|
|
|
|
init_reply("ERROR: Unknown commitment, recovering our funds!");
|
|
|
|
}
|
|
|
|
|
2020-04-02 04:41:19 +02:00
|
|
|
/* update our accounting notions for this channel.
|
|
|
|
* should result in a channel balance of zero */
|
2020-04-03 03:46:18 +02:00
|
|
|
if (!is_replay)
|
2020-05-26 05:39:40 +02:00
|
|
|
update_ledger_unknown(&tx->txid, tx_blockheight, amt_salvaged);
|
2020-04-02 04:41:19 +02:00
|
|
|
|
2018-08-17 07:06:36 +02:00
|
|
|
/* Tell master to give up on HTLCs immediately. */
|
|
|
|
for (size_t i = 0; i < tal_count(htlcs); i++) {
|
|
|
|
u8 *msg;
|
|
|
|
|
|
|
|
if (!tell_if_missing[i])
|
|
|
|
continue;
|
|
|
|
|
2020-08-25 04:15:48 +02:00
|
|
|
msg = towire_onchaind_missing_htlc_output(NULL, &htlcs[i]);
|
2018-08-17 07:06:36 +02:00
|
|
|
wire_sync_write(REQ_FD, take(msg));
|
|
|
|
}
|
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
wait_for_resolved(outs);
|
2018-08-17 07:06:36 +02:00
|
|
|
}
|
|
|
|
|
2020-12-03 02:22:01 +01:00
|
|
|
static int cmp_htlc_cltv(const struct htlc_stub *a,
|
|
|
|
const struct htlc_stub *b, void *unused)
|
|
|
|
{
|
|
|
|
if (a->cltv_expiry < b->cltv_expiry)
|
|
|
|
return -1;
|
|
|
|
else if (a->cltv_expiry > b->cltv_expiry)
|
|
|
|
return 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-08-23 03:52:17 +02:00
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
2018-04-25 12:55:34 +02:00
|
|
|
setup_locale();
|
|
|
|
|
2018-03-15 07:10:20 +01:00
|
|
|
const tal_t *ctx = tal(NULL, char);
|
2017-08-23 03:52:17 +02:00
|
|
|
u8 *msg;
|
2018-07-09 13:17:59 +02:00
|
|
|
struct pubkey remote_per_commit_point, old_remote_per_commit_point;
|
2019-09-09 18:11:24 +02:00
|
|
|
enum side opener;
|
2018-07-23 04:23:02 +02:00
|
|
|
struct basepoints basepoints[NUM_SIDES];
|
2017-08-23 03:52:17 +02:00
|
|
|
struct shachain shachain;
|
2020-05-26 05:39:40 +02:00
|
|
|
struct tx_parts *tx;
|
2017-08-23 03:52:17 +02:00
|
|
|
struct tracked_output **outs;
|
2020-05-26 05:39:40 +02:00
|
|
|
struct bitcoin_txid our_broadcast_txid, tmptxid;
|
2020-08-13 19:45:02 +02:00
|
|
|
struct bitcoin_signature *remote_htlc_sigs;
|
2019-02-21 04:45:55 +01:00
|
|
|
struct amount_sat funding;
|
|
|
|
u64 num_htlcs;
|
2017-08-23 03:52:17 +02:00
|
|
|
u8 *scriptpubkey[NUM_SIDES];
|
|
|
|
struct htlc_stub *htlcs;
|
2017-09-26 23:02:47 +02:00
|
|
|
bool *tell_if_missing, *tell_immediately;
|
2020-05-26 05:39:40 +02:00
|
|
|
u32 locktime, tx_blockheight;
|
2018-08-17 07:06:36 +02:00
|
|
|
struct pubkey *possible_remote_per_commitment_point;
|
2020-04-02 04:35:52 +02:00
|
|
|
int mutual_outnum;
|
2020-04-03 03:46:18 +02:00
|
|
|
bool open_is_replay;
|
2017-08-23 03:52:17 +02:00
|
|
|
|
2018-01-08 11:01:09 +01:00
|
|
|
subdaemon_setup(argc, argv);
|
2017-08-23 03:52:17 +02:00
|
|
|
|
|
|
|
status_setup_sync(REQ_FD);
|
|
|
|
|
2017-09-26 23:02:47 +02:00
|
|
|
missing_htlc_msgs = tal_arr(ctx, u8 *, 0);
|
|
|
|
|
2018-03-15 07:10:20 +01:00
|
|
|
msg = wire_sync_read(tmpctx, REQ_FD);
|
2020-08-25 04:15:48 +02:00
|
|
|
if (!fromwire_onchaind_init(tmpctx, msg,
|
2018-07-23 04:23:03 +02:00
|
|
|
&shachain,
|
2019-09-25 22:38:45 +02:00
|
|
|
&chainparams,
|
2019-02-21 04:45:55 +01:00
|
|
|
&funding,
|
2020-04-02 04:21:22 +02:00
|
|
|
&our_msat,
|
2017-08-23 03:52:17 +02:00
|
|
|
&old_remote_per_commit_point,
|
|
|
|
&remote_per_commit_point,
|
|
|
|
&to_self_delay[LOCAL],
|
|
|
|
&to_self_delay[REMOTE],
|
2020-03-10 14:11:47 +01:00
|
|
|
&delayed_to_us_feerate,
|
|
|
|
&htlc_feerate,
|
|
|
|
&penalty_feerate,
|
2019-02-21 04:45:55 +01:00
|
|
|
&dust_limit,
|
2017-08-23 03:52:17 +02:00
|
|
|
&our_broadcast_txid,
|
|
|
|
&scriptpubkey[LOCAL],
|
|
|
|
&scriptpubkey[REMOTE],
|
2017-09-16 01:38:06 +02:00
|
|
|
&our_wallet_pubkey,
|
2019-09-09 18:11:24 +02:00
|
|
|
&opener,
|
2018-07-23 04:23:03 +02:00
|
|
|
&basepoints[LOCAL],
|
2018-07-23 04:23:02 +02:00
|
|
|
&basepoints[REMOTE],
|
2018-02-08 02:25:12 +01:00
|
|
|
&tx,
|
2020-05-26 05:39:40 +02:00
|
|
|
&locktime,
|
2017-08-23 03:52:17 +02:00
|
|
|
&tx_blockheight,
|
2017-09-26 23:02:47 +02:00
|
|
|
&reasonable_depth,
|
2017-08-23 03:52:17 +02:00
|
|
|
&remote_htlc_sigs,
|
2018-04-03 06:31:48 +02:00
|
|
|
&num_htlcs,
|
|
|
|
&min_possible_feerate,
|
2018-08-17 07:06:36 +02:00
|
|
|
&max_possible_feerate,
|
2019-09-10 04:23:27 +02:00
|
|
|
&possible_remote_per_commitment_point,
|
2020-08-14 03:30:42 +02:00
|
|
|
&funding_pubkey[LOCAL],
|
|
|
|
&funding_pubkey[REMOTE],
|
2021-06-04 07:13:47 +02:00
|
|
|
&static_remotekey_start[LOCAL],
|
|
|
|
&static_remotekey_start[REMOTE],
|
2020-08-13 19:41:02 +02:00
|
|
|
&option_anchor_outputs,
|
2020-09-08 05:20:02 +02:00
|
|
|
&open_is_replay,
|
|
|
|
&min_relay_feerate)) {
|
2020-08-25 04:15:48 +02:00
|
|
|
master_badmsg(WIRE_ONCHAIND_INIT, msg);
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
2017-11-15 07:21:39 +01:00
|
|
|
|
2020-03-10 14:11:47 +01:00
|
|
|
status_debug("delayed_to_us_feerate = %u, htlc_feerate = %u, "
|
|
|
|
"penalty_feerate = %u", delayed_to_us_feerate,
|
|
|
|
htlc_feerate, penalty_feerate);
|
2018-11-22 03:17:29 +01:00
|
|
|
/* We need to keep tx around, but there's only one: not really a leak */
|
|
|
|
tal_steal(ctx, notleak(tx));
|
2017-08-23 03:52:17 +02:00
|
|
|
|
|
|
|
/* FIXME: Filter as we go, don't load them all into mem! */
|
2018-11-22 03:17:29 +01:00
|
|
|
htlcs = tal_arr(tmpctx, struct htlc_stub, num_htlcs);
|
|
|
|
tell_if_missing = tal_arr(htlcs, bool, num_htlcs);
|
|
|
|
tell_immediately = tal_arr(htlcs, bool, num_htlcs);
|
2017-09-26 23:02:47 +02:00
|
|
|
if (!htlcs || !tell_if_missing || !tell_immediately)
|
2017-09-12 06:55:52 +02:00
|
|
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
2017-08-23 03:52:17 +02:00
|
|
|
"Can't allocate %"PRIu64" htlcs", num_htlcs);
|
|
|
|
|
2017-09-05 01:42:10 +02:00
|
|
|
for (u64 i = 0; i < num_htlcs; i++) {
|
2018-03-15 07:10:20 +01:00
|
|
|
msg = wire_sync_read(tmpctx, REQ_FD);
|
2020-08-25 04:15:48 +02:00
|
|
|
if (!fromwire_onchaind_htlc(msg, &htlcs[i],
|
2017-09-26 23:02:47 +02:00
|
|
|
&tell_if_missing[i],
|
|
|
|
&tell_immediately[i]))
|
2020-08-25 04:15:48 +02:00
|
|
|
master_badmsg(WIRE_ONCHAIND_HTLC, msg);
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
|
2020-12-03 02:22:01 +01:00
|
|
|
/* Sort by CLTV, so matches are in CLTV order (and easy to skip dups) */
|
|
|
|
asort(htlcs, tal_count(htlcs), cmp_htlc_cltv, NULL);
|
|
|
|
|
2017-08-23 03:52:17 +02:00
|
|
|
outs = tal_arr(ctx, struct tracked_output *, 0);
|
2020-05-26 05:39:40 +02:00
|
|
|
wally_tx_input_get_txid(tx->inputs[0], &tmptxid);
|
2020-05-26 05:39:40 +02:00
|
|
|
new_tracked_output(&outs, &tmptxid,
|
2017-08-23 03:52:17 +02:00
|
|
|
0, /* We don't care about funding blockheight */
|
|
|
|
FUNDING_TRANSACTION,
|
2020-05-26 05:39:40 +02:00
|
|
|
tx->inputs[0]->index,
|
2019-02-21 04:45:55 +01:00
|
|
|
funding,
|
2017-09-20 06:45:41 +02:00
|
|
|
FUNDING_OUTPUT, NULL, NULL, NULL);
|
2017-08-23 03:52:17 +02:00
|
|
|
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("Remote per-commit point: %s",
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2017-08-23 03:52:17 +02:00
|
|
|
&remote_per_commit_point));
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("Old remote per-commit point: %s",
|
2018-03-15 05:30:38 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey,
|
2017-08-23 03:52:17 +02:00
|
|
|
&old_remote_per_commit_point));
|
|
|
|
|
2020-12-03 02:22:01 +01:00
|
|
|
trim_maximum_feerate(funding, tx);
|
|
|
|
|
2017-08-23 03:52:17 +02:00
|
|
|
/* BOLT #5:
|
|
|
|
*
|
|
|
|
* There are three ways a channel can end:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* 1. The good way (*mutual close*): at some point the local and
|
|
|
|
* remote nodes agree to close the channel. They generate a *closing
|
|
|
|
* transaction* (which is similar to a commitment transaction, but
|
|
|
|
* without any pending payments) and publish it on the blockchain (see
|
|
|
|
* [BOLT #2: Channel Close](02-peer-protocol.md#channel-close)).
|
2017-08-23 03:52:17 +02:00
|
|
|
*/
|
2020-04-02 04:35:52 +02:00
|
|
|
if (is_mutual_close(tx, scriptpubkey[LOCAL], scriptpubkey[REMOTE], &mutual_outnum))
|
2020-05-26 05:39:40 +02:00
|
|
|
handle_mutual_close(outs, tx,
|
2020-04-03 23:52:35 +02:00
|
|
|
tx_blockheight, mutual_outnum, open_is_replay);
|
2017-08-23 03:52:17 +02:00
|
|
|
else {
|
|
|
|
/* BOLT #5:
|
|
|
|
*
|
|
|
|
* 2. The bad way (*unilateral close*): something goes wrong,
|
2018-06-17 12:13:44 +02:00
|
|
|
* possibly without evil intent on either side. Perhaps one
|
|
|
|
* party crashed, for instance. One side publishes its
|
|
|
|
* *latest commitment transaction*.
|
2017-08-23 03:52:17 +02:00
|
|
|
*/
|
2018-08-17 06:16:33 +02:00
|
|
|
struct secret revocation_preimage;
|
2020-05-26 05:39:40 +02:00
|
|
|
commit_num = unmask_commit_number(tx, locktime, opener,
|
2018-07-23 04:23:02 +02:00
|
|
|
&basepoints[LOCAL].payment,
|
|
|
|
&basepoints[REMOTE].payment);
|
2017-08-23 03:52:17 +02:00
|
|
|
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("commitnum = %"PRIu64
|
2017-12-07 23:59:39 +01:00
|
|
|
", revocations_received = %"PRIu64,
|
2017-08-23 03:52:17 +02:00
|
|
|
commit_num, revocations_received(&shachain));
|
|
|
|
|
2020-05-26 05:39:40 +02:00
|
|
|
if (is_local_commitment(&tx->txid, &our_broadcast_txid))
|
|
|
|
handle_our_unilateral(tx, tx_blockheight,
|
2018-07-23 04:23:02 +02:00
|
|
|
basepoints,
|
2017-08-23 03:52:17 +02:00
|
|
|
htlcs,
|
2017-09-26 23:02:47 +02:00
|
|
|
tell_if_missing, tell_immediately,
|
2021-06-16 20:09:32 +02:00
|
|
|
opener,
|
2017-08-23 03:52:17 +02:00
|
|
|
remote_htlc_sigs,
|
2020-04-03 03:46:18 +02:00
|
|
|
outs,
|
|
|
|
open_is_replay);
|
2017-08-23 03:52:17 +02:00
|
|
|
/* BOLT #5:
|
|
|
|
*
|
|
|
|
* 3. The ugly way (*revoked transaction close*): one of the
|
2018-06-17 12:13:44 +02:00
|
|
|
* parties deliberately tries to cheat, by publishing an
|
|
|
|
* *outdated commitment transaction* (presumably, a prior
|
|
|
|
* version, which is more in its favor).
|
2017-08-23 03:52:17 +02:00
|
|
|
*/
|
2018-08-17 06:16:33 +02:00
|
|
|
else if (shachain_get_secret(&shachain, commit_num,
|
|
|
|
&revocation_preimage)) {
|
2020-05-26 05:39:40 +02:00
|
|
|
handle_their_cheat(tx,
|
2017-09-26 23:02:37 +02:00
|
|
|
tx_blockheight,
|
2017-08-23 03:52:17 +02:00
|
|
|
&revocation_preimage,
|
2018-07-23 04:23:02 +02:00
|
|
|
basepoints,
|
2017-09-26 23:02:47 +02:00
|
|
|
htlcs,
|
|
|
|
tell_if_missing, tell_immediately,
|
2021-06-16 20:09:32 +02:00
|
|
|
opener,
|
2020-04-03 03:46:18 +02:00
|
|
|
outs,
|
|
|
|
open_is_replay);
|
2017-08-23 03:52:17 +02:00
|
|
|
/* BOLT #5:
|
|
|
|
*
|
2018-06-17 12:13:44 +02:00
|
|
|
* There may be more than one valid, *unrevoked* commitment
|
|
|
|
* transaction after a signature has been received via
|
|
|
|
* `commitment_signed` and before the corresponding
|
|
|
|
* `revoke_and_ack`. As such, either commitment may serve as
|
|
|
|
* the *remote node's* commitment transaction; hence, the
|
|
|
|
* local node is required to handle both.
|
2017-08-23 03:52:17 +02:00
|
|
|
*/
|
|
|
|
} else if (commit_num == revocations_received(&shachain)) {
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("Their unilateral tx, old commit point");
|
2017-08-23 03:52:17 +02:00
|
|
|
handle_their_unilateral(tx, tx_blockheight,
|
|
|
|
&old_remote_per_commit_point,
|
2018-07-23 04:23:02 +02:00
|
|
|
basepoints,
|
2017-09-26 23:02:47 +02:00
|
|
|
htlcs,
|
|
|
|
tell_if_missing,
|
|
|
|
tell_immediately,
|
2021-06-16 20:09:32 +02:00
|
|
|
opener,
|
2020-04-03 03:46:18 +02:00
|
|
|
outs,
|
|
|
|
open_is_replay);
|
2017-08-23 03:52:17 +02:00
|
|
|
} else if (commit_num == revocations_received(&shachain) + 1) {
|
2019-09-08 18:39:26 +02:00
|
|
|
status_debug("Their unilateral tx, new commit point");
|
2017-08-23 03:52:17 +02:00
|
|
|
handle_their_unilateral(tx, tx_blockheight,
|
|
|
|
&remote_per_commit_point,
|
2018-07-23 04:23:02 +02:00
|
|
|
basepoints,
|
2017-09-26 23:02:47 +02:00
|
|
|
htlcs,
|
|
|
|
tell_if_missing,
|
|
|
|
tell_immediately,
|
2021-06-16 20:09:32 +02:00
|
|
|
opener,
|
2020-04-03 03:46:18 +02:00
|
|
|
outs,
|
|
|
|
open_is_replay);
|
2018-08-17 07:06:36 +02:00
|
|
|
} else {
|
|
|
|
handle_unknown_commitment(tx, tx_blockheight,
|
|
|
|
possible_remote_per_commitment_point,
|
|
|
|
basepoints,
|
|
|
|
htlcs,
|
|
|
|
tell_if_missing,
|
2020-04-03 03:46:18 +02:00
|
|
|
outs,
|
|
|
|
open_is_replay);
|
2018-08-17 07:06:36 +02:00
|
|
|
}
|
2017-08-23 03:52:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* We're done! */
|
|
|
|
tal_free(ctx);
|
2018-03-29 04:06:45 +02:00
|
|
|
daemon_shutdown();
|
2017-08-23 03:52:17 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|