global: thread zero fee option everywhere.

In most cases, it's the same as option_anchor_outputs, but for
fees it's different.  This transformation is the simplest:
pass it as a pair, and test it explicitly.

In future we could rationalize some paths, but this was nice
and mechanical.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2023-06-26 08:48:21 +09:30
parent e1a9e25412
commit af6d7c0779
38 changed files with 404 additions and 184 deletions

View File

@@ -606,7 +606,8 @@ u8 *bitcoin_wscript_htlc_offer_ripemd160(const tal_t *ctx,
const struct pubkey *remotehtlckey,
const struct ripemd160 *payment_ripemd,
const struct pubkey *revocationkey,
bool option_anchor_outputs)
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx)
{
u8 *script = tal_arr(ctx, u8, 0);
struct ripemd160 ripemd;
@@ -638,7 +639,7 @@ u8 *bitcoin_wscript_htlc_offer_ripemd160(const tal_t *ctx,
add_op(&script, OP_EQUALVERIFY);
add_op(&script, OP_CHECKSIG);
add_op(&script, OP_ENDIF);
if (option_anchor_outputs) {
if (option_anchor_outputs || option_anchors_zero_fee_htlc_tx) {
add_number(&script, 1);
add_op(&script, OP_CHECKSEQUENCEVERIFY);
add_op(&script, OP_DROP);
@@ -653,7 +654,8 @@ u8 *bitcoin_wscript_htlc_offer(const tal_t *ctx,
const struct pubkey *remotehtlckey,
const struct sha256 *payment_hash,
const struct pubkey *revocationkey,
bool option_anchor_outputs)
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx)
{
struct ripemd160 ripemd;
@@ -661,7 +663,8 @@ u8 *bitcoin_wscript_htlc_offer(const tal_t *ctx,
return bitcoin_wscript_htlc_offer_ripemd160(ctx, localhtlckey,
remotehtlckey,
&ripemd, revocationkey,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
}
/* BOLT #3:
@@ -717,7 +720,8 @@ u8 *bitcoin_wscript_htlc_receive_ripemd(const tal_t *ctx,
const struct pubkey *remotehtlckey,
const struct ripemd160 *payment_ripemd,
const struct pubkey *revocationkey,
bool option_anchor_outputs)
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx)
{
u8 *script = tal_arr(ctx, u8, 0);
struct ripemd160 ripemd;
@@ -752,7 +756,7 @@ u8 *bitcoin_wscript_htlc_receive_ripemd(const tal_t *ctx,
add_op(&script, OP_DROP);
add_op(&script, OP_CHECKSIG);
add_op(&script, OP_ENDIF);
if (option_anchor_outputs) {
if (option_anchor_outputs || option_anchors_zero_fee_htlc_tx) {
add_number(&script, 1);
add_op(&script, OP_CHECKSEQUENCEVERIFY);
add_op(&script, OP_DROP);
@@ -768,7 +772,8 @@ u8 *bitcoin_wscript_htlc_receive(const tal_t *ctx,
const struct pubkey *remotehtlckey,
const struct sha256 *payment_hash,
const struct pubkey *revocationkey,
bool option_anchor_outputs)
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx)
{
struct ripemd160 ripemd;
@@ -776,7 +781,8 @@ u8 *bitcoin_wscript_htlc_receive(const tal_t *ctx,
return bitcoin_wscript_htlc_receive_ripemd(ctx, htlc_abstimeout,
localhtlckey, remotehtlckey,
&ripemd, revocationkey,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
}
/* BOLT #3:

View File

@@ -98,7 +98,8 @@ u8 *bitcoin_wscript_htlc_offer(const tal_t *ctx,
const struct pubkey *remotehtlckey,
const struct sha256 *payment_hash,
const struct pubkey *revocationkey,
bool option_anchor_outputs);
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx);
u8 **bitcoin_witness_htlc_timeout_tx(const tal_t *ctx,
const struct bitcoin_signature *localsig,
const struct bitcoin_signature *remotesig,
@@ -109,7 +110,8 @@ u8 *bitcoin_wscript_htlc_receive(const tal_t *ctx,
const struct pubkey *remotekey,
const struct sha256 *payment_hash,
const struct pubkey *revocationkey,
bool option_anchor_outputs);
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx);
u8 **bitcoin_witness_htlc_success_tx(const tal_t *ctx,
const struct bitcoin_signature *localsig,
const struct bitcoin_signature *remotesig,
@@ -122,14 +124,16 @@ u8 *bitcoin_wscript_htlc_offer_ripemd160(const tal_t *ctx,
const struct pubkey *remotehtlckey,
const struct ripemd160 *payment_ripemd,
const struct pubkey *revocationkey,
bool option_anchor_outputs);
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx);
u8 *bitcoin_wscript_htlc_receive_ripemd(const tal_t *ctx,
const struct abs_locktime *htlc_abstimeout,
const struct pubkey *localkey,
const struct pubkey *remotekey,
const struct ripemd160 *payment_ripemd,
const struct pubkey *revocationkey,
bool option_anchor_outputs);
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx);
/* BOLT #3 HTLC-success/HTLC-timeout output */
u8 *bitcoin_wscript_htlc_tx(const tal_t *ctx,

View File

@@ -1071,8 +1071,7 @@ static struct bitcoin_signature *calc_commitsigs(const tal_t *ctx,
txs[i+1]->wtx->inputs[0].index);
msg = towire_hsmd_sign_remote_htlc_tx(NULL, txs[i + 1], wscript,
&peer->remote_per_commit,
channel_has(peer->channel,
OPT_ANCHOR_OUTPUTS));
channel_has_anchors(peer->channel));
msg = hsm_req(tmpctx, take(msg));
if (!fromwire_hsmd_sign_tx_reply(msg, &htlc_sigs[i]))
@@ -1599,7 +1598,7 @@ static void handle_peer_commit_sig(struct peer *peer, const u8 *msg)
/* SIGHASH_ALL is implied. */
commit_sig.sighash_type = SIGHASH_ALL;
htlc_sigs = unraw_sigs(tmpctx, raw_sigs,
channel_has(peer->channel, OPT_ANCHOR_OUTPUTS));
channel_has_anchors(peer->channel));
txs =
channel_txs(tmpctx, &htlc_map, NULL,
@@ -3759,9 +3758,12 @@ static void init_channel(struct peer *peer)
peer->dev_fast_gossip = dev_fast_gossip;
#endif
status_debug("option_static_remotekey = %u, option_anchor_outputs = %u",
status_debug("option_static_remotekey = %u,"
" option_anchor_outputs = %u"
" option_anchors_zero_fee_htlc_tx = %u",
channel_type_has(channel_type, OPT_STATIC_REMOTEKEY),
channel_type_has(channel_type, OPT_ANCHOR_OUTPUTS));
channel_type_has(channel_type, OPT_ANCHOR_OUTPUTS),
channel_type_has(channel_type, OPT_ANCHORS_ZERO_FEE_HTLC_TX));
/* Keeping an array of pointers is better since it allows us to avoid
* extra allocations later. */

View File

@@ -14,24 +14,29 @@ static bool trim(const struct htlc *htlc,
u32 feerate_per_kw,
struct amount_sat dust_limit,
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx,
enum side side)
{
return htlc_is_trimmed(htlc_owner(htlc), htlc->amount,
feerate_per_kw, dust_limit, side,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
}
size_t commit_tx_num_untrimmed(const struct htlc **htlcs,
u32 feerate_per_kw,
struct amount_sat dust_limit,
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx,
enum side side)
{
size_t i, n;
for (i = n = 0; i < tal_count(htlcs); i++)
n += !trim(htlcs[i], feerate_per_kw, dust_limit,
option_anchor_outputs, side);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
side);
return n;
}
@@ -40,22 +45,26 @@ bool commit_tx_amount_trimmed(const struct htlc **htlcs,
u32 feerate_per_kw,
struct amount_sat dust_limit,
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx,
enum side side,
struct amount_msat *amt)
{
for (size_t i = 0; i < tal_count(htlcs); i++) {
if (trim(htlcs[i], feerate_per_kw, dust_limit,
option_anchor_outputs, side))
option_anchor_outputs, option_anchors_zero_fee_htlc_tx,
side)) {
if (!amount_msat_add(amt, *amt, htlcs[i]->amount))
return false;
}
}
return true;
}
static void add_offered_htlc_out(struct bitcoin_tx *tx, size_t n,
const struct htlc *htlc,
const struct keyset *keyset,
bool option_anchor_outputs)
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx)
{
struct ripemd160 ripemd;
u8 *wscript, *p2wsh;
@@ -63,7 +72,8 @@ static void add_offered_htlc_out(struct bitcoin_tx *tx, size_t n,
ripemd160(&ripemd, htlc->rhash.u.u8, sizeof(htlc->rhash.u.u8));
wscript = htlc_offered_wscript(tx, &ripemd, keyset,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
p2wsh = scriptpubkey_p2wsh(tx, wscript);
bitcoin_tx_add_output(tx, p2wsh, wscript, amount);
SUPERVERBOSE("# HTLC #%" PRIu64 " offered amount %"PRIu64" wscript %s\n", htlc->id,
@@ -75,7 +85,8 @@ static void add_offered_htlc_out(struct bitcoin_tx *tx, size_t n,
static void add_received_htlc_out(struct bitcoin_tx *tx, size_t n,
const struct htlc *htlc,
const struct keyset *keyset,
bool option_anchor_outputs)
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx)
{
struct ripemd160 ripemd;
u8 *wscript, *p2wsh;
@@ -83,7 +94,8 @@ static void add_received_htlc_out(struct bitcoin_tx *tx, size_t n,
ripemd160(&ripemd, htlc->rhash.u.u8, sizeof(htlc->rhash.u.u8));
wscript = htlc_received_wscript(tx, &ripemd, &htlc->expiry, keyset,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
p2wsh = scriptpubkey_p2wsh(tx, wscript);
amount = amount_msat_to_sat_round_down(htlc->amount);
@@ -115,6 +127,7 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
struct wally_tx_output *direct_outputs[NUM_SIDES],
u64 obscured_commitment_number,
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx,
enum side side)
{
struct amount_sat base_fee;
@@ -146,6 +159,7 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
feerate_per_kw,
dust_limit,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
side);
/* BOLT #3:
@@ -154,7 +168,8 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
* fee](#fee-calculation).
*/
base_fee = commit_tx_base_fee(feerate_per_kw, untrimmed,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
SUPERVERBOSE("# base commitment transaction fee = %"PRIu64" for %zu untrimmed\n",
base_fee.satoshis /* Raw: spec uses raw numbers */, untrimmed);
@@ -165,7 +180,7 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
* of 330 sats from the funder (either `to_local` or
* `to_remote`).
*/
if (option_anchor_outputs
if ((option_anchor_outputs || option_anchors_zero_fee_htlc_tx)
&& !amount_sat_add(&base_fee, base_fee, AMOUNT_SAT(660)))
/* Can't overflow: feerate is u32. */
abort();
@@ -183,7 +198,9 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
bool ok = true;
for (size_t i = 0; i < tal_count(htlcs); i++) {
if (!trim(htlcs[i], feerate_per_kw, dust_limit,
option_anchor_outputs, side))
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
side))
ok &= amount_sat_add(&out, out, amount_msat_to_sat_round_down(htlcs[i]->amount));
}
if (amount_msat_greater_eq_sat(self_pay, dust_limit))
@@ -219,10 +236,12 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
if (htlc_owner(htlcs[i]) != side)
continue;
if (trim(htlcs[i], feerate_per_kw, dust_limit,
option_anchor_outputs, side))
option_anchor_outputs, option_anchors_zero_fee_htlc_tx,
side))
continue;
add_offered_htlc_out(tx, n, htlcs[i], keyset,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
(*htlcmap)[n] = htlcs[i];
cltvs[n] = abs_locktime_to_blocks(&htlcs[i]->expiry);
n++;
@@ -237,10 +256,12 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
if (htlc_owner(htlcs[i]) == side)
continue;
if (trim(htlcs[i], feerate_per_kw, dust_limit,
option_anchor_outputs, side))
option_anchor_outputs, option_anchors_zero_fee_htlc_tx,
side))
continue;
add_received_htlc_out(tx, n, htlcs[i], keyset,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
(*htlcmap)[n] = htlcs[i];
cltvs[n] = abs_locktime_to_blocks(&htlcs[i]->expiry);
n++;
@@ -303,7 +324,7 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
*...
* Otherwise, this output is a simple P2WPKH to `remotepubkey`.
*/
if (option_anchor_outputs) {
if (option_anchor_outputs || option_anchors_zero_fee_htlc_tx) {
redeem = bitcoin_wscript_to_remote_anchored(tmpctx,
&keyset->other_payment_key,
(!side) == lessor ?
@@ -351,7 +372,7 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
* * if `to_remote` exists or there are untrimmed HTLCs, add a
* [`to_remote_anchor` output]
*/
if (option_anchor_outputs) {
if (option_anchor_outputs || option_anchors_zero_fee_htlc_tx) {
if (to_local || untrimmed != 0) {
tx_add_anchor_output(tx, local_funding_key);
(*htlcmap)[n] = NULL;

View File

@@ -14,6 +14,7 @@ struct keyset;
* @option_anchor_outputs: does option_anchor_outputs apply to this channel?
* @side: from which side's point of view
* @option_anchor_outputs: does option_anchor_outputs apply to this channel?
* @option_anchors_zero_fee_htlc_tx: does option_anchors_zero_fee_htlc_tx apply to this channel?
*
* We need @side because HTLC fees are different for offered and
* received HTLCs.
@@ -21,6 +22,7 @@ struct keyset;
size_t commit_tx_num_untrimmed(const struct htlc **htlcs,
u32 feerate_per_kw,
struct amount_sat dust_limit,
bool option_anchors_zero_fee_htlc_tx,
bool option_anchor_outputs,
enum side side);
@@ -42,6 +44,7 @@ bool commit_tx_amount_trimmed(const struct htlc **htlcs,
u32 feerate_per_kw,
struct amount_sat dust_limit,
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx,
enum side side,
struct amount_msat *amt);
/**
@@ -86,6 +89,7 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
struct wally_tx_output *direct_outputs[NUM_SIDES],
u64 obscured_commitment_number,
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx,
enum side side);
#endif /* LIGHTNING_CHANNELD_COMMIT_TX_H */

View File

@@ -243,8 +243,14 @@ static void add_htlcs(struct bitcoin_tx ***txs,
enum side side)
{
struct bitcoin_outpoint outpoint;
u32 feerate_per_kw = channel_feerate(channel, side);
u32 htlc_feerate_per_kw;
bool option_anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS);
bool option_anchors_zero_fee_htlc_tx = channel_has(channel, OPT_ANCHORS_ZERO_FEE_HTLC_TX);
if (channel_has(channel, OPT_ANCHORS_ZERO_FEE_HTLC_TX))
htlc_feerate_per_kw = 0;
else
htlc_feerate_per_kw = channel_feerate(channel, side);
/* Get txid of commitment transaction */
bitcoin_txid((*txs)[0], &outpoint.txid);
@@ -261,27 +267,31 @@ static void add_htlcs(struct bitcoin_tx ***txs,
if (htlc_owner(htlc) == side) {
ripemd160(&ripemd, htlc->rhash.u.u8, sizeof(htlc->rhash.u.u8));
wscript = htlc_offered_wscript(tmpctx, &ripemd, keyset,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
tx = htlc_timeout_tx(*txs, chainparams, &outpoint,
wscript,
htlc->amount,
htlc->expiry.locktime,
channel->config[!side].to_self_delay,
feerate_per_kw,
htlc_feerate_per_kw,
keyset,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
} else {
ripemd160(&ripemd, htlc->rhash.u.u8, sizeof(htlc->rhash.u.u8));
wscript = htlc_received_wscript(tmpctx, &ripemd,
&htlc->expiry, keyset,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
tx = htlc_success_tx(*txs, chainparams, &outpoint,
wscript,
htlc->amount,
channel->config[!side].to_self_delay,
feerate_per_kw,
htlc_feerate_per_kw,
keyset,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
}
/* Append to array. */
@@ -334,6 +344,7 @@ struct bitcoin_tx **channel_txs(const tal_t *ctx,
channel->view[side].owed[!side], committed, htlcmap, direct_outputs,
commitment_number ^ channel->commitment_number_obscurer,
channel_has(channel, OPT_ANCHOR_OUTPUTS),
channel_has(channel, OPT_ANCHORS_ZERO_FEE_HTLC_TX),
side);
/* Set the remote/local pubkeys on the commitment tx psbt */
@@ -392,17 +403,24 @@ static bool get_room_above_reserve(const struct channel *channel,
static size_t num_untrimmed_htlcs(enum side side,
struct amount_sat dust_limit,
u32 feerate,
bool option_static_remotekey,
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx,
const struct htlc **committed,
const struct htlc **adding,
const struct htlc **removing)
{
return commit_tx_num_untrimmed(committed, feerate, dust_limit,
option_static_remotekey, side)
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
side)
+ commit_tx_num_untrimmed(adding, feerate, dust_limit,
option_static_remotekey, side)
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
side)
- commit_tx_num_untrimmed(removing, feerate, dust_limit,
option_static_remotekey, side);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
side);
}
static struct amount_sat fee_for_htlcs(const struct channel *channel,
@@ -415,12 +433,16 @@ static struct amount_sat fee_for_htlcs(const struct channel *channel,
struct amount_sat dust_limit = channel->config[side].dust_limit;
size_t untrimmed;
bool option_anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS);
bool option_anchors_zero_fee_htlc_tx = channel_has(channel, OPT_ANCHORS_ZERO_FEE_HTLC_TX);
untrimmed = num_untrimmed_htlcs(side, dust_limit, feerate,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
committed, adding, removing);
return commit_tx_base_fee(feerate, untrimmed, option_anchor_outputs);
return commit_tx_base_fee(feerate, untrimmed,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
}
static bool htlc_dust(const struct channel *channel,
@@ -433,21 +455,25 @@ static bool htlc_dust(const struct channel *channel,
{
struct amount_sat dust_limit = channel->config[side].dust_limit;
bool option_anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS);
bool option_anchors_zero_fee_htlc_tx = channel_has(channel, OPT_ANCHORS_ZERO_FEE_HTLC_TX);
struct amount_msat trim_rmvd = AMOUNT_MSAT(0);
if (!commit_tx_amount_trimmed(committed, feerate,
dust_limit,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
side, trim_total))
return false;
if (!commit_tx_amount_trimmed(adding, feerate,
dust_limit,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
side, trim_total))
return false;
if (!commit_tx_amount_trimmed(removing, feerate,
dust_limit,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
side, &trim_rmvd))
return false;
@@ -489,6 +515,7 @@ static bool local_opener_has_fee_headroom(const struct channel *channel,
size_t untrimmed;
struct amount_sat fee;
bool option_anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS);
bool option_anchors_zero_fee_htlc_tx = channel_has(channel, OPT_ANCHORS_ZERO_FEE_HTLC_TX);
assert(channel->opener == LOCAL);
@@ -497,12 +524,14 @@ static bool local_opener_has_fee_headroom(const struct channel *channel,
untrimmed = num_untrimmed_htlcs(LOCAL, channel->config[LOCAL].dust_limit,
feerate,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
committed, adding, removing);
/* Now, how much would it cost us if feerate increases 100% and we added
* another HTLC? */
fee = commit_tx_base_fee(2 * feerate, untrimmed + 1,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
if (amount_msat_greater_eq_sat(remainder, fee))
return true;
@@ -535,6 +564,7 @@ static enum channel_add_err add_htlc(struct channel *channel,
const struct channel_view *view;
size_t htlc_count;
bool option_anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS);
bool option_anchors_zero_fee_htlc_tx = channel_has(channel, OPT_ANCHORS_ZERO_FEE_HTLC_TX);
u32 feerate, feerate_ceil;
htlc = tal(tmpctx, struct htlc);
@@ -704,7 +734,7 @@ static enum channel_add_err add_htlc(struct channel *channel,
* of 330 sats from the funder (either `to_local` or
* `to_remote`).
*/
if (option_anchor_outputs
if ((option_anchor_outputs || option_anchors_zero_fee_htlc_tx)
&& channel->opener == sender
&& !amount_msat_sub_sat(&remainder, remainder, AMOUNT_SAT(660)))
return CHANNEL_ERR_CHANNEL_CAPACITY_EXCEEDED;
@@ -738,7 +768,7 @@ static enum channel_add_err add_htlc(struct channel *channel,
&remainder))
return CHANNEL_ERR_CHANNEL_CAPACITY_EXCEEDED;
if (option_anchor_outputs
if ((option_anchor_outputs || option_anchors_zero_fee_htlc_tx)
&& channel->opener != sender
&& !amount_msat_sub_sat(&remainder, remainder, AMOUNT_SAT(660)))
return CHANNEL_ERR_CHANNEL_CAPACITY_EXCEEDED;
@@ -1167,6 +1197,7 @@ u32 approx_max_feerate(const struct channel *channel)
struct amount_sat avail;
const struct htlc **committed, **adding, **removing;
bool option_anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS);
bool option_anchors_zero_fee_htlc_tx = channel_has(channel, OPT_ANCHORS_ZERO_FEE_HTLC_TX);
gather_htlcs(tmpctx, channel, !channel->opener,
&committed, &removing, &adding);
@@ -1174,7 +1205,7 @@ u32 approx_max_feerate(const struct channel *channel)
/* Assume none are trimmed; this gives lower bound on feerate. */
num = tal_count(committed) + tal_count(adding) - tal_count(removing);
weight = commit_tx_base_weight(num, option_anchor_outputs);
weight = commit_tx_base_weight(num, option_anchor_outputs, option_anchors_zero_fee_htlc_tx);
/* Available is their view */
avail = amount_msat_to_sat_round_down(channel->view[!channel->opener].owed[channel->opener]);
@@ -1185,7 +1216,7 @@ u32 approx_max_feerate(const struct channel *channel)
* of 330 sats from the funder (either `to_local` or
* `to_remote`).
*/
if (option_anchor_outputs
if ((option_anchor_outputs || option_anchors_zero_fee_htlc_tx)
&& !amount_sat_sub(&avail, avail, AMOUNT_SAT(660))) {
avail = AMOUNT_SAT(0);
} else {
@@ -1236,22 +1267,27 @@ bool can_opener_afford_feerate(const struct channel *channel, u32 feerate_per_kw
size_t untrimmed;
const struct htlc **committed, **adding, **removing;
bool option_anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS);
bool option_anchors_zero_fee_htlc_tx = channel_has(channel, OPT_ANCHORS_ZERO_FEE_HTLC_TX);
gather_htlcs(tmpctx, channel, !channel->opener,
&committed, &removing, &adding);
untrimmed = commit_tx_num_untrimmed(committed, feerate_per_kw, dust_limit,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
!channel->opener)
+ commit_tx_num_untrimmed(adding, feerate_per_kw, dust_limit,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
!channel->opener)
- commit_tx_num_untrimmed(removing, feerate_per_kw, dust_limit,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
!channel->opener);
fee = commit_tx_base_fee(feerate_per_kw, untrimmed,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
/* BOLT #3:
* If `option_anchors` applies to the commitment
@@ -1259,7 +1295,7 @@ bool can_opener_afford_feerate(const struct channel *channel, u32 feerate_per_kw
* of 330 sats from the funder (either `to_local` or
* `to_remote`).
*/
if (option_anchor_outputs
if ((option_anchor_outputs || option_anchors_zero_fee_htlc_tx)
&& !amount_sat_add(&fee, fee, AMOUNT_SAT(660)))
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Cannot add 660 sats to %s for anchor",

View File

@@ -245,7 +245,8 @@ static void report_htlcs(const struct bitcoin_tx *tx,
const struct pubkey *remote_htlckey,
const struct pubkey *remote_revocation_key,
u32 feerate_per_kw,
bool option_anchor_outputs)
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx)
{
size_t i, n;
struct bitcoin_outpoint outpoint;
@@ -291,14 +292,17 @@ static void report_htlcs(const struct bitcoin_tx *tx,
remote_htlckey,
&htlc->rhash,
remote_revocation_key,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
htlc_tx[i] = htlc_timeout_tx(htlc_tx, tx->chainparams,
&outpoint, wscript[i],
htlc->amount,
htlc->expiry.locktime,
to_self_delay,
feerate_per_kw,
&keyset, option_anchor_outputs);
&keyset,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
} else {
wscript[i] = bitcoin_wscript_htlc_receive(tmpctx,
&htlc->expiry,
@@ -306,14 +310,16 @@ static void report_htlcs(const struct bitcoin_tx *tx,
remote_htlckey,
&htlc->rhash,
remote_revocation_key,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
htlc_tx[i] = htlc_success_tx(htlc_tx, tx->chainparams,
&outpoint, wscript[i],
htlc->amount,
to_self_delay,
feerate_per_kw,
&keyset,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
}
sign_tx_input(htlc_tx[i], 0,
NULL,
@@ -344,7 +350,8 @@ static void report_htlcs(const struct bitcoin_tx *tx,
remote_revocation_key,
&localhtlcsig,
&remotehtlcsig[i],
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
} else {
htlc_success_tx_add_witness(htlc_tx[i],
&htlc->expiry,
@@ -354,7 +361,8 @@ static void report_htlcs(const struct bitcoin_tx *tx,
&remotehtlcsig[i],
htlc->r,
remote_revocation_key,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
}
printf("htlc_%s_tx (htlc #%"PRIu64"): %s\n",
htlc_owner(htlc) == LOCAL ? "timeout" : "success",
@@ -380,6 +388,7 @@ static void report(struct bitcoin_tx *tx,
const struct pubkey *remote_revocation_key,
u32 feerate_per_kw,
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx,
const struct htlc **htlc_map,
size_t total_htlcs)
{
@@ -425,7 +434,8 @@ static void report(struct bitcoin_tx *tx,
remotekey, remote_htlckey,
remote_revocation_key,
feerate_per_kw,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
}
#ifdef DEBUG
@@ -530,6 +540,7 @@ int main(int argc, const char *argv[])
struct amount_msat to_local, to_remote;
const struct htlc **htlcs, **htlc_map, **htlc_map2, **inv_htlcs;
bool option_anchor_outputs = false;
bool option_anchors_zero_fee_htlc_tx = false;
bool option_static_remotekey = false;
/* Allow us to check static-remotekey BOLT 3 vectors, too */
@@ -814,6 +825,7 @@ int main(int argc, const char *argv[])
to_remote,
NULL, &htlc_map, NULL, commitment_number ^ cn_obscurer,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
LOCAL);
print_superverbose = false;
tx2 = commit_tx(tmpctx,
@@ -830,6 +842,7 @@ int main(int argc, const char *argv[])
to_remote,
NULL, &htlc_map2, NULL, commitment_number ^ cn_obscurer,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
REMOTE);
tx_must_be_eq(tx, tx2);
report(tx, wscript, &x_remote_funding_privkey, &remote_funding_pubkey,
@@ -845,6 +858,7 @@ int main(int argc, const char *argv[])
&remote_revocation_key,
feerate_per_kw,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
htlc_map,
0);
@@ -880,6 +894,7 @@ int main(int argc, const char *argv[])
to_remote,
htlcs, &htlc_map, NULL, commitment_number ^ cn_obscurer,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
LOCAL);
print_superverbose = false;
tx2 = commit_tx(tmpctx,
@@ -897,6 +912,7 @@ int main(int argc, const char *argv[])
inv_htlcs, &htlc_map2, NULL,
commitment_number ^ cn_obscurer,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
REMOTE);
tx_must_be_eq(tx, tx2);
report(tx, wscript, &x_remote_funding_privkey, &remote_funding_pubkey,
@@ -912,6 +928,7 @@ int main(int argc, const char *argv[])
&remote_revocation_key,
feerate_per_kw,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
htlc_map,
tal_count(htlcs));
@@ -935,6 +952,7 @@ int main(int argc, const char *argv[])
htlcs, &htlc_map, NULL,
commitment_number ^ cn_obscurer,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
LOCAL);
/* This is what it would look like for peer generating it! */
tx2 = commit_tx(tmpctx,
@@ -952,6 +970,7 @@ int main(int argc, const char *argv[])
inv_htlcs, &htlc_map2, NULL,
commitment_number ^ cn_obscurer,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
REMOTE);
tx_must_be_eq(newtx, tx2);
#ifdef DEBUG
@@ -995,6 +1014,7 @@ int main(int argc, const char *argv[])
htlcs, &htlc_map, NULL,
commitment_number ^ cn_obscurer,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
LOCAL);
report(tx, wscript,
&x_remote_funding_privkey, &remote_funding_pubkey,
@@ -1010,6 +1030,7 @@ int main(int argc, const char *argv[])
&remote_revocation_key,
feerate_per_kw-1,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
htlc_map,
tal_count(htlcs));
@@ -1045,6 +1066,7 @@ int main(int argc, const char *argv[])
htlcs, &htlc_map, NULL,
commitment_number ^ cn_obscurer,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
LOCAL);
report(newtx, wscript,
&x_remote_funding_privkey, &remote_funding_pubkey,
@@ -1060,6 +1082,7 @@ int main(int argc, const char *argv[])
&remote_revocation_key,
feerate_per_kw,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
htlc_map,
tal_count(htlcs));
@@ -1074,7 +1097,8 @@ int main(int argc, const char *argv[])
for (;;) {
struct amount_sat base_fee
= commit_tx_base_fee(feerate_per_kw, 0,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
/* BOLT #3:
* If `option_anchors` applies to the commitment
@@ -1082,7 +1106,7 @@ int main(int argc, const char *argv[])
* of 330 sats from the funder (either `to_local` or
* `to_remote`).
*/
if (option_anchor_outputs
if ((option_anchor_outputs || option_anchors_zero_fee_htlc_tx)
&& !amount_sat_add(&base_fee, base_fee, AMOUNT_SAT(660)))
abort();
@@ -1121,6 +1145,7 @@ int main(int argc, const char *argv[])
htlcs, &htlc_map, NULL,
commitment_number ^ cn_obscurer,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
LOCAL);
report(tx, wscript,
&x_remote_funding_privkey, &remote_funding_pubkey,
@@ -1136,6 +1161,7 @@ int main(int argc, const char *argv[])
&remote_revocation_key,
feerate_per_kw,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
htlc_map,
tal_count(htlcs));
break;
@@ -1176,6 +1202,7 @@ int main(int argc, const char *argv[])
to_remote,
htlcs, &htlc_map, NULL, commitment_number ^ cn_obscurer,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
LOCAL);
print_superverbose = false;
tx2 = commit_tx(tmpctx,
@@ -1193,6 +1220,7 @@ int main(int argc, const char *argv[])
inv_htlcs, &htlc_map2, NULL,
commitment_number ^ cn_obscurer,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
REMOTE);
tx_must_be_eq(tx, tx2);
report(tx, wscript, &x_remote_funding_privkey, &remote_funding_pubkey,
@@ -1208,6 +1236,7 @@ int main(int argc, const char *argv[])
&remote_revocation_key,
feerate_per_kw,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
htlc_map,
tal_count(htlcs));
common_shutdown();

View File

@@ -362,6 +362,7 @@ int main(int argc, const char *argv[])
const struct htlc **htlc_map, **htlcs;
const u8 *funding_wscript, *funding_wscript_alt;
bool option_anchor_outputs = false;
bool option_anchors_zero_fee_htlc_tx = false;
u32 blockheight = 0;
size_t i;
@@ -534,7 +535,7 @@ int main(int argc, const char *argv[])
to_local,
to_remote,
NULL, &htlc_map, NULL, 0x2bb038521914 ^ 42,
option_anchor_outputs, LOCAL);
option_anchor_outputs, option_anchors_zero_fee_htlc_tx, LOCAL);
txs = channel_txs(tmpctx,
&htlc_map, NULL, &funding_wscript_alt,
@@ -662,7 +663,7 @@ int main(int argc, const char *argv[])
&keyset, feerate_per_kw[LOCAL], local_config->dust_limit,
to_local, to_remote, htlcs, &htlc_map, NULL,
0x2bb038521914 ^ 42,
option_anchor_outputs, LOCAL);
option_anchor_outputs, option_anchors_zero_fee_htlc_tx, LOCAL);
txs = channel_txs(tmpctx, &htlc_map, NULL, &funding_wscript,
lchannel, &local_per_commitment_point, 42,

View File

@@ -8,7 +8,8 @@ bool htlc_is_trimmed(enum side htlc_owner,
u32 feerate_per_kw,
struct amount_sat dust_limit,
enum side side,
bool option_anchor_outputs)
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx)
{
struct amount_sat htlc_fee, htlc_min;
@@ -24,7 +25,8 @@ bool htlc_is_trimmed(enum side htlc_owner,
*/
if (htlc_owner == side)
htlc_fee = htlc_timeout_fee(feerate_per_kw,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
/* BOLT #3:
*
* - for every received HTLC:
@@ -36,7 +38,8 @@ bool htlc_is_trimmed(enum side htlc_owner,
*/
else
htlc_fee = htlc_success_fee(feerate_per_kw,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
/* If these overflow, it implies htlc must be less. */
if (!amount_sat_add(&htlc_min, dust_limit, htlc_fee))

View File

@@ -10,7 +10,8 @@ bool htlc_is_trimmed(enum side htlc_owner,
u32 feerate_per_kw,
struct amount_sat dust_limit,
enum side side,
bool option_anchor_outputs);
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx);
/* Calculate the our htlc-trimming buffer feerate
* (max(25%, 10s/vbyte) above feerate_per_kw) */

View File

@@ -13,7 +13,8 @@ struct bitcoin_tx *htlc_tx(const tal_t *ctx,
const u8 *htlc_tx_wscript,
struct amount_sat htlc_fee,
u32 locktime,
bool option_anchor_outputs)
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx)
{
/* BOLT #3:
* * locktime: `0` for HTLC-success, `cltv_expiry` for HTLC-timeout
@@ -43,7 +44,7 @@ struct bitcoin_tx *htlc_tx(const tal_t *ctx,
* * `txin[0]` sequence: `0` (set to `1` for `option_anchors`)
*/
bitcoin_tx_add_input(tx, commit,
option_anchor_outputs ? 1 : 0,
(option_anchor_outputs || option_anchors_zero_fee_htlc_tx) ? 1 : 0,
NULL, amount, NULL, commit_wscript);
/* BOLT #3:
@@ -54,6 +55,7 @@ struct bitcoin_tx *htlc_tx(const tal_t *ctx,
* * `txout[0]` script: version-0 P2WSH with witness script as shown
* below
*/
/* Note: for option_anchors_zero_fee_htlc_tx, htlc_fee is 0 */
if (!amount_sat_sub(&amount, amount, htlc_fee))
return tal_free(tx);
@@ -74,7 +76,8 @@ struct bitcoin_tx *htlc_success_tx(const tal_t *ctx,
u16 to_self_delay,
u32 feerate_per_kw,
const struct keyset *keyset,
bool option_anchor_outputs)
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx)
{
const u8 *htlc_wscript;
@@ -90,9 +93,11 @@ struct bitcoin_tx *htlc_success_tx(const tal_t *ctx,
amount_msat_to_sat_round_down(htlc_msatoshi),
htlc_wscript,
htlc_success_fee(feerate_per_kw,
option_anchor_outputs),
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx),
0,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
}
/* Fill in the witness for HTLC-success tx produced above. */
@@ -104,7 +109,8 @@ void htlc_success_tx_add_witness(struct bitcoin_tx *htlc_success,
const struct bitcoin_signature *remotehtlcsig,
const struct preimage *payment_preimage,
const struct pubkey *revocationkey,
bool option_anchor_outputs)
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx)
{
struct sha256 hash;
u8 *wscript, **witness;
@@ -114,7 +120,8 @@ void htlc_success_tx_add_witness(struct bitcoin_tx *htlc_success,
htlc_abstimeout,
localhtlckey, remotehtlckey,
&hash, revocationkey,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
witness = bitcoin_witness_htlc_success_tx(htlc_success,
localhtlcsig, remotehtlcsig,
@@ -132,7 +139,8 @@ struct bitcoin_tx *htlc_timeout_tx(const tal_t *ctx,
u16 to_self_delay,
u32 feerate_per_kw,
const struct keyset *keyset,
bool option_anchor_outputs)
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx)
{
const u8 *htlc_wscript;
@@ -148,9 +156,11 @@ struct bitcoin_tx *htlc_timeout_tx(const tal_t *ctx,
amount_msat_to_sat_round_down(htlc_msatoshi),
htlc_wscript,
htlc_timeout_fee(feerate_per_kw,
option_anchor_outputs),
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx),
cltv_expiry,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
}
/* Fill in the witness for HTLC-timeout tx produced above. */
@@ -161,13 +171,15 @@ void htlc_timeout_tx_add_witness(struct bitcoin_tx *htlc_timeout,
const struct pubkey *revocationkey,
const struct bitcoin_signature *localhtlcsig,
const struct bitcoin_signature *remotehtlcsig,
bool option_anchor_outputs)
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx)
{
u8 **witness;
u8 *wscript = bitcoin_wscript_htlc_offer(htlc_timeout,
localhtlckey, remotehtlckey,
payment_hash, revocationkey,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
witness = bitcoin_witness_htlc_timeout_tx(htlc_timeout, localhtlcsig,
remotehtlcsig, wscript);
@@ -178,21 +190,24 @@ void htlc_timeout_tx_add_witness(struct bitcoin_tx *htlc_timeout,
u8 *htlc_offered_wscript(const tal_t *ctx,
const struct ripemd160 *ripemd,
const struct keyset *keyset,
bool option_anchor_outputs)
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx)
{
return bitcoin_wscript_htlc_offer_ripemd160(ctx,
&keyset->self_htlc_key,
&keyset->other_htlc_key,
ripemd,
&keyset->self_revocation_key,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
}
u8 *htlc_received_wscript(const tal_t *ctx,
const struct ripemd160 *ripemd,
const struct abs_locktime *expiry,
const struct keyset *keyset,
bool option_anchor_outputs)
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx)
{
return bitcoin_wscript_htlc_receive_ripemd(ctx,
expiry,
@@ -200,5 +215,6 @@ u8 *htlc_received_wscript(const tal_t *ctx,
&keyset->other_htlc_key,
ripemd,
&keyset->self_revocation_key,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
}

View File

@@ -14,17 +14,23 @@ struct pubkey;
struct ripemd160;
static inline struct amount_sat htlc_timeout_fee(u32 feerate_per_kw,
bool option_anchor_outputs)
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx)
{
/* BOLT #3:
*
* The fee for an HTLC-timeout transaction:
*...
* - If `option_anchors_zero_fee_htlc_tx` applies:
* 1. MUST be 0.
* - Otherwise, MUST be calculated to match:
* 1. Multiply `feerate_per_kw` by 663 (666 if `option_anchor_outputs`
* applies) and divide by 1000 (rounding down).
*/
u32 base;
if (option_anchors_zero_fee_htlc_tx)
return AMOUNT_SAT(0);
if (option_anchor_outputs)
base = 666;
else
@@ -34,17 +40,23 @@ static inline struct amount_sat htlc_timeout_fee(u32 feerate_per_kw,
}
static inline struct amount_sat htlc_success_fee(u32 feerate_per_kw,
bool option_anchor_outputs)
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx)
{
/* BOLT #3:
*
* The fee for an HTLC-success transaction:
*...
* - If `option_anchors_zero_fee_htlc_tx` applies:
* 1. MUST be 0.
* - Otherwise, MUST be calculated to match:
* 1. Multiply `feerate_per_kw` by 703 (706 if `option_anchor_outputs`
* applies) and divide by 1000 (rounding down).
*/
u32 base;
if (option_anchors_zero_fee_htlc_tx)
return AMOUNT_SAT(0);
if (option_anchor_outputs)
base = 706;
else
@@ -63,7 +75,8 @@ struct bitcoin_tx *htlc_success_tx(const tal_t *ctx,
u16 to_self_delay,
u32 feerate_per_kw,
const struct keyset *keyset,
bool option_anchor_outputs);
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx);
/* Fill in the witness for HTLC-success tx produced above. */
void htlc_success_tx_add_witness(struct bitcoin_tx *htlc_success,
@@ -74,7 +87,8 @@ void htlc_success_tx_add_witness(struct bitcoin_tx *htlc_success,
const struct bitcoin_signature *remotesig,
const struct preimage *payment_preimage,
const struct pubkey *revocationkey,
bool option_anchor_outputs);
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx);
/* Create HTLC-timeout tx to spend an offered HTLC commitment tx
* output; doesn't fill in input witness. */
@@ -87,7 +101,8 @@ struct bitcoin_tx *htlc_timeout_tx(const tal_t *ctx,
u16 to_self_delay,
u32 feerate_per_kw,
const struct keyset *keyset,
bool option_anchor_outputs);
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx);
/* Fill in the witness for HTLC-timeout tx produced above. */
void htlc_timeout_tx_add_witness(struct bitcoin_tx *htlc_timeout,
@@ -97,8 +112,8 @@ void htlc_timeout_tx_add_witness(struct bitcoin_tx *htlc_timeout,
const struct pubkey *revocationkey,
const struct bitcoin_signature *localsig,
const struct bitcoin_signature *remotesig,
bool option_anchor_outputs);
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx);
/* Generate the witness script for an HTLC the other side offered:
* scriptpubkey_p2wsh(ctx, wscript) gives the scriptpubkey */
@@ -106,14 +121,16 @@ u8 *htlc_received_wscript(const tal_t *ctx,
const struct ripemd160 *ripemd,
const struct abs_locktime *expiry,
const struct keyset *keyset,
bool option_anchor_outputs);
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx);
/* Generate the witness script for an HTLC this side offered:
* scriptpubkey_p2wsh(ctx, wscript) gives the scriptpubkey */
u8 *htlc_offered_wscript(const tal_t *ctx,
const struct ripemd160 *ripemd,
const struct keyset *keyset,
bool option_anchor_outputs);
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx);
/* Low-level HTLC tx creator */
struct bitcoin_tx *htlc_tx(const tal_t *ctx,
@@ -124,5 +141,6 @@ struct bitcoin_tx *htlc_tx(const tal_t *ctx,
const u8 *htlc_tx_wscript,
struct amount_sat htlc_fee,
u32 locktime,
bool option_anchor_outputs);
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx);
#endif /* LIGHTNING_COMMON_HTLC_TX_H */

View File

@@ -134,6 +134,7 @@ struct bitcoin_tx *initial_channel_tx(const tal_t *ctx,
direct_outputs,
side, csv_lock,
channel_has(channel, OPT_ANCHOR_OUTPUTS),
channel_has(channel, OPT_ANCHORS_ZERO_FEE_HTLC_TX),
err_reason);
if (init_tx) {

View File

@@ -88,6 +88,7 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx,
enum side side,
u32 csv_lock,
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx,
char** err_reason)
{
struct amount_sat base_fee;
@@ -122,15 +123,16 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx,
* fee](#fee-calculation).
*/
base_fee = commit_tx_base_fee(feerate_per_kw, untrimmed,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
/* BOLT:
* If `option_anchor_outputs` applies to the commitment
/* BOLT #3:
* If `option_anchors` applies to the commitment
* transaction, also subtract two times the fixed anchor size
* of 330 sats from the funder (either `to_local` or
* `to_remote`).
*/
if (option_anchor_outputs
if ((option_anchor_outputs || option_anchors_zero_fee_htlc_tx)
&& !amount_sat_add(&base_fee, base_fee, AMOUNT_SAT(660))) {
*err_reason = "Funder cannot afford anchor outputs";
return NULL;
@@ -246,7 +248,7 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx,
u8 *redeem;
amount = amount_msat_to_sat_round_down(other_pay);
if (option_anchor_outputs) {
if (option_anchor_outputs || option_anchors_zero_fee_htlc_tx) {
redeem = bitcoin_wscript_to_remote_anchored(tmpctx,
&keyset->other_payment_key,
(!side) == lessor ? csv_lock : 1);
@@ -271,7 +273,7 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx,
* * if `to_remote` exists or there are untrimmed HTLCs, add a
* [`to_remote_anchor` output]
*/
if (option_anchor_outputs) {
if (option_anchor_outputs || option_anchors_zero_fee_htlc_tx) {
if (to_local || untrimmed != 0) {
tx_add_anchor_output(tx, &funding_key[side]);
output_order[n] = NULL;

View File

@@ -25,7 +25,8 @@ u64 commit_number_obscurer(const struct pubkey *opener_payment_basepoint,
/* The base weight of a commitment tx */
static inline size_t commit_tx_base_weight(size_t num_untrimmed_htlcs,
bool option_anchor_outputs)
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx)
{
size_t weight;
size_t num_outputs;
@@ -36,7 +37,7 @@ static inline size_t commit_tx_base_weight(size_t num_untrimmed_htlcs,
* - MUST be calculated to match:
* 1. Start with `weight` = 724 (1124 if `option_anchors` applies).
*/
if (option_anchor_outputs) {
if (option_anchor_outputs || option_anchors_zero_fee_htlc_tx) {
weight = 1124;
num_outputs = 4;
} else {
@@ -61,11 +62,13 @@ static inline size_t commit_tx_base_weight(size_t num_untrimmed_htlcs,
/* Helper to calculate the base fee if we have this many htlc outputs */
static inline struct amount_sat commit_tx_base_fee(u32 feerate_per_kw,
size_t num_untrimmed_htlcs,
bool option_anchor_outputs)
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx)
{
return amount_tx_fee(feerate_per_kw,
commit_tx_base_weight(num_untrimmed_htlcs,
option_anchor_outputs));
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx));
}
/**
@@ -107,6 +110,7 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx,
enum side side,
u32 csv_lock,
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx,
char** err_reason);
/* try_subtract_fee - take away this fee from the opener (and return true), or all if insufficient (and return false). */

View File

@@ -22,7 +22,7 @@ void towire_utxo(u8 **pptr, const struct utxo *utxo)
towire_bool(pptr, utxo->close_info->commitment_point != NULL);
if (utxo->close_info->commitment_point)
towire_pubkey(pptr, utxo->close_info->commitment_point);
towire_bool(pptr, utxo->close_info->option_anchor_outputs);
towire_bool(pptr, utxo->close_info->option_anchors);
towire_u32(pptr, utxo->close_info->csv);
}
@@ -51,7 +51,7 @@ struct utxo *fromwire_utxo(const tal_t *ctx, const u8 **ptr, size_t *max)
utxo->close_info->commitment_point);
} else
utxo->close_info->commitment_point = NULL;
utxo->close_info->option_anchor_outputs
utxo->close_info->option_anchors
= fromwire_bool(ptr, max);
utxo->close_info->csv = fromwire_u32(ptr, max);
} else {

View File

@@ -11,7 +11,7 @@ struct ext_key;
struct unilateral_close_info {
u64 channel_id;
struct node_id peer_id;
bool option_anchor_outputs;
bool option_anchors;
/* NULL if this is an option_static_remotekey commitment */
struct pubkey *commitment_point;
u32 csv;
@@ -71,8 +71,11 @@ static inline bool utxo_is_csv_locked(const struct utxo *utxo, u32 current_heigh
{
if (!utxo->close_info)
return false;
/* All close outputs are csv locked for option_anchor_outputs */
if (!utxo->blockheight && utxo->close_info->option_anchor_outputs)
/* BOLT #3:
* If `option_anchors` applies to the commitment transaction, the
* `to_remote` output is encumbered by a one block csv lock.
*/
if (!utxo->blockheight && utxo->close_info->option_anchors)
return true;
assert(*utxo->blockheight + utxo->close_info->csv > *utxo->blockheight);
return *utxo->blockheight + utxo->close_info->csv > current_height;

View File

@@ -111,7 +111,8 @@ int main(int argc, char *argv[])
argnum++;
fee = commit_tx_base_fee(feerate_per_kw, 0,
option_anchor_outputs);
option_anchor_outputs,
false);
/* BOLT #3:
* If `option_anchors` applies to the commitment
* transaction, also subtract two times the fixed anchor size

View File

@@ -492,7 +492,7 @@ static void sign_our_inputs(struct utxo **utxos, struct wally_psbt *psbt)
psbt_input_add_pubkey(psbt, j, &pubkey);
/* It's actually a P2WSH in this case. */
if (utxo->close_info && utxo->close_info->option_anchor_outputs) {
if (utxo->close_info && utxo->close_info->option_anchors) {
const u8 *wscript
= bitcoin_wscript_to_remote_anchored(tmpctx,
&pubkey,

View File

@@ -106,7 +106,7 @@ struct anchor_details *create_anchor_details(const tal_t *ctx,
struct anchor_details *adet = tal(ctx, struct anchor_details);
/* If we don't have an anchor, we can't do anything. */
if (!channel_has(channel, OPT_ANCHOR_OUTPUTS))
if (!channel_type_has_anchors(channel->type))
return tal_free(adet);
if (!hsm_capable(ld, WIRE_HSMD_SIGN_ANCHORSPEND)) {

View File

@@ -750,7 +750,9 @@ static struct command_result *json_feerates(struct command *cmd,
/* It actually is negotiated per-channel... */
bool anchor_outputs
= feature_offered(cmd->ld->our_features->bits[INIT_FEATURE],
OPT_ANCHOR_OUTPUTS);
OPT_ANCHOR_OUTPUTS)
|| feature_offered(cmd->ld->our_features->bits[INIT_FEATURE],
OPT_ANCHORS_ZERO_FEE_HTLC_TX);
json_object_start(response, "onchain_fee_estimates");
/* eg 020000000001016f51de645a47baa49a636b8ec974c28bdff0ac9151c0f4eda2dbe3b41dbe711d000000001716001401fad90abcd66697e2592164722de4a95ebee165ffffffff0240420f00000000002200205b8cd3b914cf67cdd8fa6273c930353dd36476734fbd962102c2df53b90880cdb73f890000000000160014c2ccab171c2a5be9dab52ec41b825863024c54660248304502210088f65e054dbc2d8f679de3e40150069854863efa4a45103b2bb63d060322f94702200d3ae8923924a458cffb0b7360179790830027bb6b29715ba03e12fc22365de1012103d745445c9362665f22e0d96e9e766f273f3260dea39c8a76bfa05dd2684ddccf00000000 == weight 702 */
@@ -773,10 +775,10 @@ static struct command_result *json_feerates(struct command *cmd,
json_add_u64(response, "htlc_timeout_satoshis",
htlc_timeout_fee(htlc_resolution_feerate(cmd->ld->topology),
false).satoshis /* Raw: estimate */);
false, false).satoshis /* Raw: estimate */);
json_add_u64(response, "htlc_success_satoshis",
htlc_success_fee(htlc_resolution_feerate(cmd->ld->topology),
false).satoshis /* Raw: estimate */);
false, false).satoshis /* Raw: estimate */);
json_object_end(response);
}

View File

@@ -359,6 +359,7 @@ void peer_start_closingd(struct channel *channel, struct peer_fd *peer_fd)
struct lightningd *ld = channel->peer->ld;
u32 final_commit_feerate;
bool option_anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS);
bool option_anchors_zero_fee_htlc_tx = channel_has(channel, OPT_ANCHORS_ZERO_FEE_HTLC_TX);
if (!channel->shutdown_scriptpubkey[REMOTE]) {
channel_internal_error(channel,
@@ -403,7 +404,8 @@ void peer_start_closingd(struct channel *channel, struct peer_fd *peer_fd)
final_commit_feerate = get_feerate(channel->fee_states,
channel->opener, LOCAL);
feelimit = commit_tx_base_fee(final_commit_feerate, 0,
option_anchor_outputs);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
/* If we can't determine feerate, start at half unilateral feerate. */
feerate = mutual_close_feerate(ld->topology);
@@ -415,7 +417,7 @@ void peer_start_closingd(struct channel *channel, struct peer_fd *peer_fd)
/* We use a feerate if anchor_outputs, otherwise max fee is set by
* the final unilateral. */
if (option_anchor_outputs) {
if (option_anchor_outputs || option_anchors_zero_fee_htlc_tx) {
max_feerate = tal(tmpctx, u32);
/* Aim for reasonable max, but use final if we don't know. */
*max_feerate = unilateral_feerate(ld->topology, false);
@@ -499,7 +501,8 @@ void peer_start_closingd(struct channel *channel, struct peer_fd *peer_fd)
(channel->closing_fee_negotiation_step == 50
&& channel->closing_fee_negotiation_step_unit == CLOSING_FEE_NEGOTIATION_STEP_UNIT_PERCENTAGE)
/* Always use quickclose with anchors */
|| option_anchor_outputs,
|| option_anchor_outputs
|| option_anchors_zero_fee_htlc_tx,
channel->shutdown_wrong_funding);
/* We don't expect a response: it will give us feedback on

View File

@@ -165,6 +165,11 @@ void json_add_unsaved_channel(struct json_stream *response,
OPT_ANCHOR_OUTPUTS))
json_add_string(response, NULL, "option_anchor_outputs");
if (feature_negotiated(channel->peer->ld->our_features,
channel->peer->their_features,
OPT_ANCHORS_ZERO_FEE_HTLC_TX))
json_add_string(response, NULL, "option_anchors_zero_fee_htlc_tx");
json_array_end(response);
json_object_end(response);
}

View File

@@ -560,7 +560,7 @@ static u8 *sign_htlc_success(const tal_t *ctx,
const struct bitcoin_tx *tx,
const struct onchain_signing_info *info)
{
const bool anchor_outputs = channel_has(info->channel, OPT_ANCHOR_OUTPUTS);
const bool anchor_outputs = channel_type_has_anchors(info->channel->type);
assert(info->msgtype == WIRE_ONCHAIND_SPEND_HTLC_SUCCESS);
return towire_hsmd_sign_any_local_htlc_tx(ctx,
@@ -576,7 +576,7 @@ static u8 *sign_htlc_timeout(const tal_t *ctx,
const struct bitcoin_tx *tx,
const struct onchain_signing_info *info)
{
const bool anchor_outputs = channel_has(info->channel, OPT_ANCHOR_OUTPUTS);
const bool anchor_outputs = channel_type_has_anchors(info->channel->type);
assert(info->msgtype == WIRE_ONCHAIND_SPEND_HTLC_TIMEOUT);
return towire_hsmd_sign_any_local_htlc_tx(ctx,
@@ -592,7 +592,7 @@ static u8 *sign_fulfill(const tal_t *ctx,
const struct bitcoin_tx *tx,
const struct onchain_signing_info *info)
{
const bool anchor_outputs = channel_has(info->channel, OPT_ANCHOR_OUTPUTS);
const bool anchor_outputs = channel_type_has_anchors(info->channel->type);
assert(info->msgtype == WIRE_ONCHAIND_SPEND_FULFILL);
return towire_hsmd_sign_any_remote_htlc_to_us(ctx,
@@ -608,7 +608,7 @@ static u8 *sign_htlc_expired(const tal_t *ctx,
const struct bitcoin_tx *tx,
const struct onchain_signing_info *info)
{
const bool anchor_outputs = channel_has(info->channel, OPT_ANCHOR_OUTPUTS);
const bool anchor_outputs = channel_type_has_anchors(info->channel->type);
assert(info->msgtype == WIRE_ONCHAIND_SPEND_HTLC_EXPIRED);
return towire_hsmd_sign_any_remote_htlc_to_us(ctx,
@@ -867,7 +867,7 @@ static bool consider_onchain_htlc_tx_rebroadcast(struct channel *channel,
struct lightningd *ld = channel->peer->ld;
/* We can't do much without anchor outputs (we could CPFP?) */
if (!channel_has(channel, OPT_ANCHOR_OUTPUTS))
if (!channel_type_has_anchors(channel->type))
return true;
/* Note that we can have UTXOs taken from us if there are a lot of
@@ -1166,7 +1166,7 @@ static void handle_onchaind_spend_fulfill(struct channel *channel,
struct amount_sat out_sats;
struct preimage preimage;
u64 htlc_id;
const bool anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS);
const bool anchor_outputs = channel_type_has_anchors(channel->type);
info = new_signing_info(msg, channel, WIRE_ONCHAIND_SPEND_FULFILL);
info->minblock = 0;
@@ -1209,7 +1209,8 @@ static void handle_onchaind_spend_htlc_success(struct channel *channel,
u8 **witness;
struct bitcoin_signature sig;
const struct onchain_witness_element **welements;
const bool anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS);
const bool option_anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS);
const bool option_anchors_zero_fee_htlc_tx = channel_has(channel, OPT_ANCHORS_ZERO_FEE_HTLC_TX);
info = new_signing_info(msg, channel, WIRE_ONCHAIND_SPEND_HTLC_SUCCESS);
info->minblock = 0;
@@ -1231,7 +1232,7 @@ static void handle_onchaind_spend_htlc_success(struct channel *channel,
* * locktime: `0` for HTLC-success, `cltv_expiry` for HTLC-timeout
*/
tx = htlc_tx(NULL, chainparams, &out, info->wscript, out_sats, htlc_wscript, fee,
0, anchor_outputs);
0, option_anchor_outputs, option_anchors_zero_fee_htlc_tx);
tal_free(htlc_wscript);
if (!tx) {
/* Can only happen if fee > out_sats */
@@ -1289,7 +1290,8 @@ static void handle_onchaind_spend_htlc_timeout(struct channel *channel,
u8 **witness;
struct bitcoin_signature sig;
const struct onchain_witness_element **welements;
const bool anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS);
const bool option_anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS);
const bool option_anchors_zero_fee_htlc_tx = channel_has(channel, OPT_ANCHORS_ZERO_FEE_HTLC_TX);
info = new_signing_info(msg, channel, WIRE_ONCHAIND_SPEND_HTLC_TIMEOUT);
@@ -1310,7 +1312,7 @@ static void handle_onchaind_spend_htlc_timeout(struct channel *channel,
* * locktime: `0` for HTLC-success, `cltv_expiry` for HTLC-timeout
*/
tx = htlc_tx(NULL, chainparams, &out, info->wscript, out_sats, htlc_wscript, fee,
cltv_expiry, anchor_outputs);
cltv_expiry, option_anchor_outputs, option_anchors_zero_fee_htlc_tx);
tal_free(htlc_wscript);
if (!tx) {
/* Can only happen if fee > out_sats */
@@ -1364,7 +1366,7 @@ static void handle_onchaind_spend_htlc_expired(struct channel *channel,
struct amount_sat out_sats;
u64 htlc_id;
u32 cltv_expiry;
const bool anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS);
const bool anchor_outputs = channel_type_has_anchors(channel->type);
info = new_signing_info(msg, channel, WIRE_ONCHAIND_SPEND_HTLC_EXPIRED);

View File

@@ -76,6 +76,12 @@ void json_add_uncommitted_channel(struct json_stream *response,
uc->peer->their_features,
OPT_ANCHOR_OUTPUTS))
json_add_string(response, NULL, "option_anchor_outputs");
if (feature_negotiated(uc->peer->ld->our_features,
uc->peer->their_features,
OPT_ANCHORS_ZERO_FEE_HTLC_TX))
json_add_string(response, NULL, "option_anchors_zero_fee_htlc_tx");
json_array_end(response);
json_object_end(response);
}

View File

@@ -473,7 +473,8 @@ static void json_add_htlcs(struct lightningd *ld,
htlc_state_name(hin->hstate));
if (htlc_is_trimmed(REMOTE, hin->msat, local_feerate,
channel->our_config.dust_limit, LOCAL,
channel_has(channel, OPT_ANCHOR_OUTPUTS)))
channel_has(channel, OPT_ANCHOR_OUTPUTS),
channel_has(channel, OPT_ANCHORS_ZERO_FEE_HTLC_TX)))
json_add_bool(response, "local_trimmed", true);
if (hin->status != NULL)
json_add_string(response, "status", hin->status);
@@ -496,7 +497,8 @@ static void json_add_htlcs(struct lightningd *ld,
htlc_state_name(hout->hstate));
if (htlc_is_trimmed(LOCAL, hout->msat, local_feerate,
channel->our_config.dust_limit, LOCAL,
channel_has(channel, OPT_ANCHOR_OUTPUTS)))
channel_has(channel, OPT_ANCHOR_OUTPUTS),
channel_has(channel, OPT_ANCHORS_ZERO_FEE_HTLC_TX)))
json_add_bool(response, "local_trimmed", true);
json_object_end(response);
}
@@ -520,6 +522,7 @@ static struct amount_sat commit_txfee(const struct channel *channel,
struct amount_sat dust_limit;
struct amount_sat fee;
bool option_anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS);
bool option_anchors_zero_fee_htlc_tx = channel_has(channel, OPT_ANCHORS_ZERO_FEE_HTLC_TX);
if (side == LOCAL)
dust_limit = channel->our_config.dust_limit;
@@ -528,7 +531,7 @@ static struct amount_sat commit_txfee(const struct channel *channel,
/* Assume we tried to add "amount" */
if (!htlc_is_trimmed(side, amount, feerate, dust_limit, side,
option_anchor_outputs))
option_anchor_outputs, option_anchors_zero_fee_htlc_tx))
num_untrimmed_htlcs++;
for (hin = htlc_in_map_first(ld->htlcs_in, &ini);
@@ -537,7 +540,7 @@ static struct amount_sat commit_txfee(const struct channel *channel,
if (hin->key.channel != channel)
continue;
if (!htlc_is_trimmed(!side, hin->msat, feerate, dust_limit,
side, option_anchor_outputs))
side, option_anchor_outputs, option_anchors_zero_fee_htlc_tx))
num_untrimmed_htlcs++;
}
for (hout = htlc_out_map_first(ld->htlcs_out, &outi);
@@ -546,7 +549,7 @@ static struct amount_sat commit_txfee(const struct channel *channel,
if (hout->key.channel != channel)
continue;
if (!htlc_is_trimmed(side, hout->msat, feerate, dust_limit,
side, option_anchor_outputs))
side, option_anchor_outputs, option_anchors_zero_fee_htlc_tx))
num_untrimmed_htlcs++;
}
@@ -563,9 +566,9 @@ static struct amount_sat commit_txfee(const struct channel *channel,
* predictability between implementations.
*/
fee = commit_tx_base_fee(2 * feerate, num_untrimmed_htlcs + 1,
option_anchor_outputs);
option_anchor_outputs, option_anchors_zero_fee_htlc_tx);
if (option_anchor_outputs) {
if (option_anchor_outputs || option_anchors_zero_fee_htlc_tx) {
/* BOLT #3:
* If `option_anchors` applies to the commitment
* transaction, also subtract two times the fixed anchor size
@@ -869,6 +872,8 @@ static void json_add_channel(struct lightningd *ld,
json_add_string(response, NULL, "option_static_remotekey");
if (channel_has(channel, OPT_ANCHOR_OUTPUTS))
json_add_string(response, NULL, "option_anchor_outputs");
if (channel_has(channel, OPT_ANCHORS_ZERO_FEE_HTLC_TX))
json_add_string(response, NULL, "option_anchors_zero_fee_htlc_tx");
if (channel_has(channel, OPT_ZEROCONF))
json_add_string(response, NULL, "option_zeroconf");
if (channel_has(channel, OPT_SCID_ALIAS))

View File

@@ -314,7 +314,8 @@ bool htlc_is_trimmed(enum side htlc_owner UNNEEDED,
u32 feerate_per_kw UNNEEDED,
struct amount_sat dust_limit UNNEEDED,
enum side side UNNEEDED,
bool option_anchor_outputs UNNEEDED)
bool option_anchor_outputs UNNEEDED,
bool option_anchors_zero_fee_htlc_tx UNNEEDED)
{ fprintf(stderr, "htlc_is_trimmed called!\n"); abort(); }
/* Generated stub for htlc_max_possible_send */
struct amount_msat htlc_max_possible_send(const struct channel *channel UNNEEDED)

View File

@@ -544,7 +544,9 @@ static struct amount_sat get_htlc_success_fee(struct tracked_output *out)
htlc_amount,
to_self_delay[LOCAL],
0,
keyset, option_anchor_outputs);
keyset,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
/* BOLT #3:
*
@@ -1822,7 +1824,8 @@ static u8 **derive_htlc_scripts(const struct htlc_stub *htlcs, enum side side)
htlc_scripts[i] = htlc_offered_wscript(htlc_scripts,
&htlcs[i].ripemd,
keyset,
option_anchor_outputs || option_anchors_zero_fee_htlc_tx);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
else {
/* FIXME: remove abs_locktime */
struct abs_locktime ltime;
@@ -1835,7 +1838,8 @@ static u8 **derive_htlc_scripts(const struct htlc_stub *htlcs, enum side side)
&htlcs[i].ripemd,
&ltime,
keyset,
option_anchor_outputs || option_anchors_zero_fee_htlc_tx);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
}
}
return htlc_scripts;
@@ -1883,7 +1887,8 @@ static size_t resolve_our_htlc_ourcommit(struct tracked_output *out,
htlc_scripts[matches[i]], htlc_amount,
htlcs[matches[i]].cltv_expiry,
to_self_delay[LOCAL], 0, keyset,
option_anchor_outputs || option_anchors_zero_fee_htlc_tx);
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
if (set_htlc_timeout_fee(tx, out->remote_htlc_sig,
htlc_scripts[matches[i]]))

View File

@@ -61,14 +61,16 @@ enum wallet_tx_type fromwire_wallet_tx_type(const u8 **cursor UNNEEDED, size_t *
u8 *htlc_offered_wscript(const tal_t *ctx UNNEEDED,
const struct ripemd160 *ripemd UNNEEDED,
const struct keyset *keyset UNNEEDED,
bool option_anchor_outputs UNNEEDED)
bool option_anchor_outputs UNNEEDED,
bool option_anchors_zero_fee_htlc_tx UNNEEDED)
{ fprintf(stderr, "htlc_offered_wscript called!\n"); abort(); }
/* Generated stub for htlc_received_wscript */
u8 *htlc_received_wscript(const tal_t *ctx UNNEEDED,
const struct ripemd160 *ripemd UNNEEDED,
const struct abs_locktime *expiry UNNEEDED,
const struct keyset *keyset UNNEEDED,
bool option_anchor_outputs UNNEEDED)
bool option_anchor_outputs UNNEEDED,
bool option_anchors_zero_fee_htlc_tx UNNEEDED)
{ fprintf(stderr, "htlc_received_wscript called!\n"); abort(); }
/* Generated stub for htlc_success_tx */
struct bitcoin_tx *htlc_success_tx(const tal_t *ctx UNNEEDED,
@@ -79,7 +81,8 @@ struct bitcoin_tx *htlc_success_tx(const tal_t *ctx UNNEEDED,
u16 to_self_delay UNNEEDED,
u32 feerate_per_kw UNNEEDED,
const struct keyset *keyset UNNEEDED,
bool option_anchor_outputs UNNEEDED)
bool option_anchor_outputs UNNEEDED,
bool option_anchors_zero_fee_htlc_tx UNNEEDED)
{ fprintf(stderr, "htlc_success_tx called!\n"); abort(); }
/* Generated stub for master_badmsg */
void master_badmsg(u32 type_expected UNNEEDED, const u8 *msg)
@@ -303,7 +306,8 @@ struct bitcoin_tx *htlc_timeout_tx(const tal_t *ctx,
u16 to_self_delay UNNEEDED,
u32 feerate_per_kw UNNEEDED,
const struct keyset *keyset UNNEEDED,
bool option_anchor_outputs)
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx)
{
struct bitcoin_tx *tx;
struct amount_sat in_amount;

View File

@@ -95,14 +95,16 @@ void fromwire_u8_array(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, u8 *arr
u8 *htlc_offered_wscript(const tal_t *ctx UNNEEDED,
const struct ripemd160 *ripemd UNNEEDED,
const struct keyset *keyset UNNEEDED,
bool option_anchor_outputs UNNEEDED)
bool option_anchor_outputs UNNEEDED,
bool option_anchors_zero_fee_htlc_tx UNNEEDED)
{ fprintf(stderr, "htlc_offered_wscript called!\n"); abort(); }
/* Generated stub for htlc_received_wscript */
u8 *htlc_received_wscript(const tal_t *ctx UNNEEDED,
const struct ripemd160 *ripemd UNNEEDED,
const struct abs_locktime *expiry UNNEEDED,
const struct keyset *keyset UNNEEDED,
bool option_anchor_outputs UNNEEDED)
bool option_anchor_outputs UNNEEDED,
bool option_anchors_zero_fee_htlc_tx UNNEEDED)
{ fprintf(stderr, "htlc_received_wscript called!\n"); abort(); }
/* Generated stub for htlc_success_tx */
struct bitcoin_tx *htlc_success_tx(const tal_t *ctx UNNEEDED,
@@ -113,7 +115,8 @@ struct bitcoin_tx *htlc_success_tx(const tal_t *ctx UNNEEDED,
u16 to_self_delay UNNEEDED,
u32 feerate_per_kw UNNEEDED,
const struct keyset *keyset UNNEEDED,
bool option_anchor_outputs UNNEEDED)
bool option_anchor_outputs UNNEEDED,
bool option_anchors_zero_fee_htlc_tx UNNEEDED)
{ fprintf(stderr, "htlc_success_tx called!\n"); abort(); }
/* Generated stub for htlc_timeout_tx */
struct bitcoin_tx *htlc_timeout_tx(const tal_t *ctx UNNEEDED,
@@ -125,7 +128,8 @@ struct bitcoin_tx *htlc_timeout_tx(const tal_t *ctx UNNEEDED,
u16 to_self_delay UNNEEDED,
u32 feerate_per_kw UNNEEDED,
const struct keyset *keyset UNNEEDED,
bool option_anchor_outputs UNNEEDED)
bool option_anchor_outputs UNNEEDED,
bool option_anchors_zero_fee_htlc_tx UNNEEDED)
{ fprintf(stderr, "htlc_timeout_tx called!\n"); abort(); }
/* Generated stub for master_badmsg */
void master_badmsg(u32 type_expected UNNEEDED, const u8 *msg)

View File

@@ -21,6 +21,7 @@ bool check_config_bounds(const tal_t *ctx,
const struct channel_config *remoteconf,
const struct channel_config *localconf,
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx,
char **err_reason)
{
struct amount_sat capacity;
@@ -72,7 +73,7 @@ bool check_config_bounds(const tal_t *ctx,
* `to_remote_anchor` above its reserve.
*/
/* (We simply include in "reserve" here if they opened). */
if (option_anchor_outputs
if ((option_anchor_outputs || option_anchors_zero_fee_htlc_tx)
&& !amount_sat_add(&reserve, reserve, AMOUNT_SAT(660))) {
*err_reason = tal_fmt(ctx,
"cannot add anchors to reserve %s",
@@ -96,7 +97,9 @@ bool check_config_bounds(const tal_t *ctx,
/* They have to pay for fees, too. Assuming HTLC is dust, though,
* we don't account for an HTLC output. */
fee = commit_tx_base_fee(feerate_per_kw, 0, option_anchor_outputs);
fee = commit_tx_base_fee(feerate_per_kw, 0,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
if (!amount_sat_sub(&capacity, capacity, fee)) {
*err_reason = tal_fmt(ctx, "channel_reserve_satoshis %s"
" and %s plus fee %s too large for "

View File

@@ -17,6 +17,7 @@ bool check_config_bounds(const tal_t *ctx,
const struct channel_config *remoteconf,
const struct channel_config *localconf,
bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx,
char **err_reason);
bool anchors_negotiated(struct feature_set *our_features,

View File

@@ -2499,8 +2499,12 @@ static void accepter_start(struct state *state, const u8 *oc2_msg)
state->min_effective_htlc_capacity,
&tx_state->remoteconf,
&tx_state->localconf,
anchors_negotiated(state->our_features,
state->their_features),
feature_negotiated(state->our_features,
state->their_features,
OPT_ANCHOR_OUTPUTS),
feature_negotiated(state->our_features,
state->their_features,
OPT_ANCHORS_ZERO_FEE_HTLC_TX),
&err_reason)) {
negotiation_failed(state, "%s", err_reason);
return;
@@ -3305,8 +3309,12 @@ static void opener_start(struct state *state, u8 *msg)
state->min_effective_htlc_capacity,
&tx_state->remoteconf,
&tx_state->localconf,
anchors_negotiated(state->our_features,
state->their_features),
feature_negotiated(state->our_features,
state->their_features,
OPT_ANCHOR_OUTPUTS),
feature_negotiated(state->our_features,
state->their_features,
OPT_ANCHORS_ZERO_FEE_HTLC_TX),
&err_reason)) {
negotiation_failed(state, "%s", err_reason);
return;
@@ -3615,8 +3623,12 @@ static void rbf_local_start(struct state *state, u8 *msg)
state->min_effective_htlc_capacity,
&tx_state->remoteconf,
&tx_state->localconf,
anchors_negotiated(state->our_features,
state->their_features),
feature_negotiated(state->our_features,
state->their_features,
OPT_ANCHOR_OUTPUTS),
feature_negotiated(state->our_features,
state->their_features,
OPT_ANCHORS_ZERO_FEE_HTLC_TX),
&err_reason)) {
open_abort(state, "%s", err_reason);
return;
@@ -3753,8 +3765,12 @@ static void rbf_remote_start(struct state *state, const u8 *rbf_msg)
state->min_effective_htlc_capacity,
&tx_state->remoteconf,
&tx_state->localconf,
anchors_negotiated(state->our_features,
state->their_features),
feature_negotiated(state->our_features,
state->their_features,
OPT_ANCHOR_OUTPUTS),
feature_negotiated(state->our_features,
state->their_features,
OPT_ANCHORS_ZERO_FEE_HTLC_TX),
&err_reason)) {
negotiation_failed(state, "%s", err_reason);
goto free_rbf_ctx;

View File

@@ -567,8 +567,12 @@ static u8 *funder_channel_start(struct state *state, u8 channel_flags,
state->min_effective_htlc_capacity,
&state->remoteconf,
&state->localconf,
anchors_negotiated(state->our_features,
state->their_features),
feature_negotiated(state->our_features,
state->their_features,
OPT_ANCHOR_OUTPUTS),
feature_negotiated(state->our_features,
state->their_features,
OPT_ANCHORS_ZERO_FEE_HTLC_TX),
&err_reason)) {
negotiation_failed(state, "%s", err_reason);
return NULL;
@@ -1085,8 +1089,12 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
state->min_effective_htlc_capacity,
&state->remoteconf,
&state->localconf,
anchors_negotiated(state->our_features,
state->their_features),
feature_negotiated(state->our_features,
state->their_features,
OPT_ANCHOR_OUTPUTS),
feature_negotiated(state->our_features,
state->their_features,
OPT_ANCHORS_ZERO_FEE_HTLC_TX),
&err_reason)) {
negotiation_failed(state, "%s", err_reason);
return NULL;

View File

@@ -1455,7 +1455,7 @@ def test_penalty_htlc_tx_timeout(node_factory, bitcoind, chainparams):
# reconnect with l1, which will fulfill the payment
l2.rpc.connect(l1.info['id'], 'localhost', l1.port)
l2.daemon.wait_for_log('got commitsig .*: feerate 11000, blockheight: 0, 0 added, 1 fulfilled, 0 failed, 0 changed')
l2.daemon.wait_for_log('got commitsig .*: feerate {}, blockheight: 0, 0 added, 1 fulfilled, 0 failed, 0 changed'.format(3750 if anchor_expected() else 11000))
# l2 moves on for closed l3
bitcoind.generate_block(1, wait_for_mempool=1)

View File

@@ -305,7 +305,7 @@ struct wally_psbt *psbt_using_utxos(const tal_t *ctx,
* set to `1` and witness:
*/
if (utxos[i]->close_info
&& utxos[i]->close_info->option_anchor_outputs)
&& utxos[i]->close_info->option_anchors)
this_nsequence = utxos[i]->close_info->csv;
else
this_nsequence = nsequence;

View File

@@ -234,7 +234,8 @@ bool htlc_is_trimmed(enum side htlc_owner UNNEEDED,
u32 feerate_per_kw UNNEEDED,
struct amount_sat dust_limit UNNEEDED,
enum side side UNNEEDED,
bool option_anchor_outputs UNNEEDED)
bool option_anchor_outputs UNNEEDED,
bool option_anchors_zero_fee_htlc_tx UNNEEDED)
{ fprintf(stderr, "htlc_is_trimmed called!\n"); abort(); }
/* Generated stub for htlc_set_add */
void htlc_set_add(struct lightningd *ld UNNEEDED,
@@ -1105,7 +1106,7 @@ static bool test_wallet_outputs(struct lightningd *ld, const tal_t *ctx)
u.close_info->channel_id = 42;
u.close_info->peer_id = id;
u.close_info->commitment_point = &pk;
u.close_info->option_anchor_outputs = false;
u.close_info->option_anchors = false;
/* Arbitrarily set scriptpubkey len to 20 */
u.scriptPubkey = tal_arr(w, u8, 20);
memset(u.scriptPubkey, 1, 20);
@@ -1130,7 +1131,7 @@ static bool test_wallet_outputs(struct lightningd *ld, const tal_t *ctx)
CHECK(u.close_info->channel_id == 42 &&
pubkey_eq(u.close_info->commitment_point, &pk) &&
node_id_eq(&u.close_info->peer_id, &id) &&
u.close_info->option_anchor_outputs == false);
u.close_info->option_anchors == false);
/* Attempt to reserve the utxo */
CHECK_MSG(wallet_update_output_status(w, &u.outpoint,
@@ -1163,7 +1164,7 @@ static bool test_wallet_outputs(struct lightningd *ld, const tal_t *ctx)
u.close_info->channel_id = 42;
u.close_info->peer_id = id;
u.close_info->commitment_point = NULL;
u.close_info->option_anchor_outputs = true;
u.close_info->option_anchors = true;
/* The blockheight has to be set for an option_anchor_output
* closed UTXO to be spendable */
u32 *blockheight = tal(w, u32);
@@ -1217,7 +1218,7 @@ static bool test_wallet_outputs(struct lightningd *ld, const tal_t *ctx)
CHECK(u.close_info->channel_id == 42 &&
u.close_info->commitment_point == NULL &&
node_id_eq(&u.close_info->peer_id, &id) &&
u.close_info->option_anchor_outputs == true &&
u.close_info->option_anchors == true &&
u.close_info->csv == 1);
/* Now un-reserve them */
tal_free(utxos);
@@ -1238,7 +1239,7 @@ static bool test_wallet_outputs(struct lightningd *ld, const tal_t *ctx)
CHECK(u.close_info->channel_id == 42 &&
u.close_info->commitment_point == NULL &&
node_id_eq(&u.close_info->peer_id, &id) &&
u.close_info->option_anchor_outputs == true &&
u.close_info->option_anchors == true &&
u.close_info->csv > 0);
}
/* Now un-reserve them */

View File

@@ -189,7 +189,7 @@ static bool wallet_add_utxo(struct wallet *w, struct utxo *utxo,
db_bind_pubkey(stmt, 8, utxo->close_info->commitment_point);
else
db_bind_null(stmt, 8);
db_bind_int(stmt, 9, utxo->close_info->option_anchor_outputs);
db_bind_int(stmt, 9, utxo->close_info->option_anchors);
} else {
db_bind_null(stmt, 6);
db_bind_null(stmt, 7);
@@ -239,7 +239,7 @@ static struct utxo *wallet_stmt2output(const tal_t *ctx, struct db_stmt *stmt)
= db_col_optional(utxo->close_info, stmt,
"commitment_point",
pubkey);
utxo->close_info->option_anchor_outputs
utxo->close_info->option_anchors
= db_col_int(stmt, "option_anchor_outputs");
utxo->close_info->csv = db_col_int(stmt, "csv_lock");
} else {
@@ -519,9 +519,11 @@ static bool deep_enough(u32 maxheight, const struct utxo *utxo,
u32 current_blockheight)
{
if (utxo->close_info
&& utxo->close_info->option_anchor_outputs) {
/* All option_anchor_output close_infos
* have a csv of at least 1 */
&& utxo->close_info->option_anchors) {
/* BOLT #3:
* If `option_anchors` applies to the commitment transaction, the
* `to_remote` output is encumbered by a one block csv lock.
*/
if (!utxo->blockheight)
return false;
@@ -658,7 +660,8 @@ bool wallet_add_onchaind_utxo(struct wallet *w,
else
db_bind_null(stmt, 8);
db_bind_int(stmt, 9, channel_has(channel, OPT_ANCHOR_OUTPUTS));
db_bind_int(stmt, 9,
channel_type_has_anchors(channel->type));
db_bind_int(stmt, 10, blockheight);
/* spendheight */
@@ -896,7 +899,7 @@ done:
static struct bitcoin_signature *
wallet_htlc_sigs_load(const tal_t *ctx, struct wallet *w, u64 channelid,
bool option_anchor_outputs)
bool option_anchors)
{
struct db_stmt *stmt;
struct bitcoin_signature *htlc_sigs = tal_arr(ctx, struct bitcoin_signature, 0);
@@ -916,7 +919,7 @@ wallet_htlc_sigs_load(const tal_t *ctx, struct wallet *w, u64 channelid,
* transaction, `SIGHASH_SINGLE|SIGHASH_ANYONECANPAY` is
* used as described in [BOLT #5]
*/
if (option_anchor_outputs)
if (option_anchors)
sig.sighash_type = SIGHASH_SINGLE|SIGHASH_ANYONECANPAY;
else
sig.sighash_type = SIGHASH_ALL;
@@ -1526,8 +1529,7 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm
&last_sig,
wallet_htlc_sigs_load(tmpctx, w,
db_col_u64(stmt, "id"),
channel_type_has(type, OPT_ANCHOR_OUTPUTS)
|| channel_type_has(type, OPT_ANCHORS_ZERO_FEE_HTLC_TX)),
channel_type_has_anchors(type)),
&channel_info,
take(fee_states),
remote_shutdown_scriptpubkey,