-
Notifications
You must be signed in to change notification settings - Fork 912
/
watchtower.c
130 lines (113 loc) · 4.33 KB
/
watchtower.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include "config.h"
#include <bitcoin/feerate.h>
#include <bitcoin/script.h>
#include <channeld/channeld.h>
#include <channeld/watchtower.h>
#include <common/features.h>
#include <common/htlc_tx.h>
#include <common/keyset.h>
#include <common/psbt_keypath.h>
#include <common/status.h>
#include <common/type_to_string.h>
#include <hsmd/hsmd_wiregen.h>
#include <wire/wire_sync.h>
static const u8 ONE = 0x1;
const struct bitcoin_tx *
penalty_tx_create(const tal_t *ctx,
const struct channel *channel,
u32 penalty_feerate,
u32 *final_index,
struct ext_key *final_ext_key,
u8 *final_scriptpubkey,
const struct secret *revocation_preimage,
const struct bitcoin_txid *commitment_txid,
s16 to_them_outnum, struct amount_sat to_them_sats,
int hsm_fd)
{
u8 *wscript;
struct bitcoin_tx *tx;
struct keyset keyset;
size_t weight;
const u8 *msg;
struct amount_sat fee, min_out, amt;
struct bitcoin_signature sig;
u32 locktime = 0;
bool option_static_remotekey = channel_has(channel, OPT_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;
struct bitcoin_outpoint outpoint;
if (to_them_outnum == -1 ||
amount_sat_less_eq(to_them_sats, dust_limit)) {
status_debug(
"Cannot create penalty transaction because there "
"is no non-dust to_them output in the commitment.");
return NULL;
}
outpoint.txid = *commitment_txid;
outpoint.n = to_them_outnum;
if (!pubkey_from_secret(&remote_per_commitment_secret, &remote_per_commitment_point))
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"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))
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Failed deriving keyset");
/* FIXME: csv_lock */
wscript = bitcoin_wscript_to_local(tmpctx, remote_to_self_delay, 1,
&keyset.self_revocation_key,
&keyset.self_delayed_payment_key);
tx = bitcoin_tx(ctx, chainparams, 1, 1, locktime);
bitcoin_tx_add_input(tx, &outpoint, 0xFFFFFFFF,
NULL, to_them_sats, NULL, wscript);
bitcoin_tx_add_output(tx, final_scriptpubkey, NULL, to_them_sats);
assert((final_index == NULL) == (final_ext_key == NULL));
if (final_index)
psbt_add_keypath_to_last_output(tx, *final_index, final_ext_key, is_p2tr(final_scriptpubkey, NULL));
/* Worst-case sig is 73 bytes */
weight = bitcoin_tx_weight(tx) + 1 + 3 + 73 + 0 + tal_count(wscript);
weight += elements_tx_overhead(chainparams, 1, 1);
fee = amount_tx_fee(penalty_feerate, weight);
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));
if (amount_sat_less(to_them_sats, min_out)) {
/* FIXME: We should use SIGHASH_NONE so others can take it */
/* We use the minimum possible fee here; if it doesn't
* propagate, who cares? */
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_failed(STATUS_FAIL_INTERNAL_ERROR,
"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_hsmd_sign_penalty_to_us(tmpctx, &remote_per_commitment_secret,
tx, wscript);
msg = hsm_req(tmpctx, hsm_sign_msg);
if (!fromwire_hsmd_sign_tx_reply(msg, &sig))
status_failed(STATUS_FAIL_HSM_IO,
"Reading sign_tx_reply: %s", tal_hex(tmpctx, msg));
witness = bitcoin_witness_sig_and_element(tx, &sig, &ONE, sizeof(ONE),
wscript);
bitcoin_tx_input_set_witness(tx, 0, take(witness));
return tx;
}