mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-26 20:30:59 +01:00
watchtower: Add function to create penalty transactions
This commit is contained in:
parent
68705444f6
commit
93eaf3017d
5 changed files with 146 additions and 3 deletions
|
@ -16,14 +16,17 @@ LIGHTNINGD_CHANNEL_HEADERS_NOGEN := \
|
||||||
channeld/channeld_htlc.h \
|
channeld/channeld_htlc.h \
|
||||||
channeld/commit_tx.h \
|
channeld/commit_tx.h \
|
||||||
channeld/full_channel.h \
|
channeld/full_channel.h \
|
||||||
channeld/full_channel_error.h
|
channeld/full_channel_error.h \
|
||||||
|
channeld/watchtower.h
|
||||||
|
|
||||||
LIGHTNINGD_CHANNEL_HEADERS := $(LIGHTNINGD_CHANNEL_HEADERS_GEN) $(LIGHTNINGD_CHANNEL_HEADERS_NOGEN)
|
LIGHTNINGD_CHANNEL_HEADERS := $(LIGHTNINGD_CHANNEL_HEADERS_GEN) $(LIGHTNINGD_CHANNEL_HEADERS_NOGEN)
|
||||||
|
|
||||||
LIGHTNINGD_CHANNEL_SRC := channeld/channeld.c \
|
LIGHTNINGD_CHANNEL_SRC := channeld/channeld.c \
|
||||||
channeld/commit_tx.c \
|
channeld/commit_tx.c \
|
||||||
channeld/full_channel.c \
|
channeld/full_channel.c \
|
||||||
channeld/gen_channel_wire.c
|
channeld/gen_channel_wire.c \
|
||||||
|
channeld/watchtower.c
|
||||||
|
|
||||||
LIGHTNINGD_CHANNEL_OBJS := $(LIGHTNINGD_CHANNEL_SRC:.c=.o)
|
LIGHTNINGD_CHANNEL_OBJS := $(LIGHTNINGD_CHANNEL_SRC:.c=.o)
|
||||||
|
|
||||||
# Make sure these depend on everything.
|
# Make sure these depend on everything.
|
||||||
|
|
120
channeld/watchtower.c
Normal file
120
channeld/watchtower.c
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
#include "watchtower.h"
|
||||||
|
|
||||||
|
#include <bitcoin/feerate.h>
|
||||||
|
#include <bitcoin/script.h>
|
||||||
|
#include <bitcoin/signature.h>
|
||||||
|
#include <bitcoin/tx.h>
|
||||||
|
#include <common/htlc_tx.h>
|
||||||
|
#include <common/key_derive.h>
|
||||||
|
#include <common/keyset.h>
|
||||||
|
#include <common/status.h>
|
||||||
|
#include <common/type_to_string.h>
|
||||||
|
#include <hsmd/gen_hsm_wire.h>
|
||||||
|
#include <wire/wire_sync.h>
|
||||||
|
|
||||||
|
static const u8 ONE = 0x1;
|
||||||
|
#define HSM_FD 6
|
||||||
|
|
||||||
|
const struct bitcoin_tx *
|
||||||
|
penalty_tx_create(const tal_t *ctx,
|
||||||
|
const struct channel *channel,
|
||||||
|
u32 penalty_feerate,
|
||||||
|
u8 *final_scriptpubkey,
|
||||||
|
const struct secret *revocation_preimage,
|
||||||
|
const struct bitcoin_txid *commitment_txid,
|
||||||
|
s16 to_them_outnum, struct amount_sat to_them_sats)
|
||||||
|
{
|
||||||
|
u8 *wscript;
|
||||||
|
struct bitcoin_tx *tx;
|
||||||
|
struct keyset keyset;
|
||||||
|
size_t weight;
|
||||||
|
u8 *msg;
|
||||||
|
struct amount_sat fee, min_out, amt;
|
||||||
|
struct bitcoin_signature sig;
|
||||||
|
u32 locktime = 0;
|
||||||
|
bool option_static_remotekey = channel->option_static_remotekey;
|
||||||
|
u8 **witness;
|
||||||
|
u32 remote_to_self_delay = channel->config[REMOTE].to_self_delay;
|
||||||
|
const struct amount_sat dust_limit = channel->config[LOCAL].dust_limit;
|
||||||
|
BUILD_ASSERT(sizeof(struct secret) == sizeof(*revocation_preimage));
|
||||||
|
const struct secret remote_per_commitment_secret = *revocation_preimage;
|
||||||
|
struct pubkey remote_per_commitment_point;
|
||||||
|
const struct basepoints *basepoints = channel->basepoints;
|
||||||
|
|
||||||
|
if (to_them_outnum == -1 ||
|
||||||
|
amount_sat_less_eq(to_them_sats, dust_limit)) {
|
||||||
|
status_unusual(
|
||||||
|
"Cannot create penalty transaction because there "
|
||||||
|
"is no non-dust to_them output in the commitment.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pubkey_from_secret(&remote_per_commitment_secret, &remote_per_commitment_point))
|
||||||
|
status_broken("Failed derive from per_commitment_secret %s",
|
||||||
|
type_to_string(tmpctx, struct secret,
|
||||||
|
&remote_per_commitment_secret));
|
||||||
|
|
||||||
|
if (!derive_keyset(&remote_per_commitment_point,
|
||||||
|
&basepoints[REMOTE],
|
||||||
|
&basepoints[LOCAL],
|
||||||
|
option_static_remotekey,
|
||||||
|
&keyset))
|
||||||
|
abort(); /* TODO(cdecker) Handle a bit more gracefully */
|
||||||
|
|
||||||
|
wscript = bitcoin_wscript_to_local(tmpctx, remote_to_self_delay,
|
||||||
|
&keyset.self_revocation_key,
|
||||||
|
&keyset.self_delayed_payment_key);
|
||||||
|
|
||||||
|
tx = bitcoin_tx(ctx, chainparams, 1, 1, locktime);
|
||||||
|
bitcoin_tx_add_input(tx, commitment_txid, to_them_outnum, 0xFFFFFFFF,
|
||||||
|
to_them_sats, NULL);
|
||||||
|
|
||||||
|
bitcoin_tx_add_output(tx, final_scriptpubkey, to_them_sats);
|
||||||
|
|
||||||
|
/* Worst-case sig is 73 bytes */
|
||||||
|
weight = bitcoin_tx_weight(tx) + 1 + 3 + 73 + 0 + tal_count(wscript);
|
||||||
|
weight = elements_add_overhead(weight, 1, 1);
|
||||||
|
fee = amount_tx_fee(penalty_feerate, weight);
|
||||||
|
|
||||||
|
if (!amount_sat_add(&min_out, dust_limit, fee))
|
||||||
|
status_broken(
|
||||||
|
"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));
|
||||||
|
|
||||||
|
if (amount_sat_less(to_them_sats, min_out)) {
|
||||||
|
/* FIXME: We should use SIGHASH_NONE so others can take it */
|
||||||
|
fee = amount_tx_fee(feerate_floor(), weight);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This can only happen if feerate_floor() is still too high; shouldn't
|
||||||
|
* happen! */
|
||||||
|
if (!amount_sat_sub(&amt, to_them_sats, fee)) {
|
||||||
|
amt = dust_limit;
|
||||||
|
status_broken(
|
||||||
|
"TX can't afford minimal feerate"
|
||||||
|
"; setting output to %s",
|
||||||
|
type_to_string(tmpctx, struct amount_sat, &amt));
|
||||||
|
}
|
||||||
|
bitcoin_tx_output_set_amount(tx, 0, amt);
|
||||||
|
bitcoin_tx_finalize(tx);
|
||||||
|
|
||||||
|
u8 *hsm_sign_msg =
|
||||||
|
towire_hsm_sign_penalty_to_us(ctx, &remote_per_commitment_secret, tx,
|
||||||
|
wscript, *tx->input_amounts[0]);
|
||||||
|
|
||||||
|
if (!wire_sync_write(HSM_FD, take(hsm_sign_msg)))
|
||||||
|
status_broken("Writing sign request to hsm");
|
||||||
|
|
||||||
|
msg = wire_sync_read(tmpctx, HSM_FD);
|
||||||
|
if (!msg || !fromwire_hsm_sign_tx_reply(msg, &sig)) {
|
||||||
|
status_broken("Reading sign_tx_reply: %s", tal_hex(tmpctx, msg));
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
witness = bitcoin_witness_sig_and_element(tx, &sig, &ONE, sizeof(ONE),
|
||||||
|
wscript);
|
||||||
|
|
||||||
|
bitcoin_tx_input_set_witness(tx, 0, take(witness));
|
||||||
|
return tx;
|
||||||
|
}
|
18
channeld/watchtower.h
Normal file
18
channeld/watchtower.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#ifndef LIGHTNING_CHANNELD_WATCHTOWER_H
|
||||||
|
#define LIGHTNING_CHANNELD_WATCHTOWER_H
|
||||||
|
#include "config.h"
|
||||||
|
#include <ccan/short_types/short_types.h>
|
||||||
|
#include <ccan/tal/tal.h>
|
||||||
|
#include <common/derive_basepoints.h>
|
||||||
|
#include <common/initial_channel.h>
|
||||||
|
|
||||||
|
const struct bitcoin_tx *
|
||||||
|
penalty_tx_create(const tal_t *ctx,
|
||||||
|
const struct channel *channel,
|
||||||
|
u32 penalty_feerate,
|
||||||
|
u8 *final_scriptpubkey,
|
||||||
|
const struct secret *revocation_preimage,
|
||||||
|
const struct bitcoin_txid *commitment_txid,
|
||||||
|
s16 to_them_outnum, struct amount_sat to_them_sats);
|
||||||
|
|
||||||
|
#endif /* LIGHTNING_CHANNELD_WATCHTOWER_H */
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include <bitcoin/pubkey.h>
|
#include <bitcoin/pubkey.h>
|
||||||
#include <bitcoin/shadouble.h>
|
#include <bitcoin/shadouble.h>
|
||||||
|
#include <bitcoin/tx.h>
|
||||||
#include <ccan/short_types/short_types.h>
|
#include <ccan/short_types/short_types.h>
|
||||||
#include <ccan/tal/tal.h>
|
#include <ccan/tal/tal.h>
|
||||||
#include <common/amount.h>
|
#include <common/amount.h>
|
||||||
|
|
|
@ -42,6 +42,7 @@ LIGHTNINGD_COMMON_OBJS := \
|
||||||
common/htlc_trim.o \
|
common/htlc_trim.o \
|
||||||
common/htlc_wire.o \
|
common/htlc_wire.o \
|
||||||
common/key_derive.o \
|
common/key_derive.o \
|
||||||
|
common/keyset.o \
|
||||||
common/io_lock.o \
|
common/io_lock.o \
|
||||||
common/json.o \
|
common/json.o \
|
||||||
common/json_helpers.o \
|
common/json_helpers.o \
|
||||||
|
|
Loading…
Add table
Reference in a new issue