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

View File

@@ -98,7 +98,8 @@ u8 *bitcoin_wscript_htlc_offer(const tal_t *ctx,
const struct pubkey *remotehtlckey, const struct pubkey *remotehtlckey,
const struct sha256 *payment_hash, const struct sha256 *payment_hash,
const struct pubkey *revocationkey, 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, u8 **bitcoin_witness_htlc_timeout_tx(const tal_t *ctx,
const struct bitcoin_signature *localsig, const struct bitcoin_signature *localsig,
const struct bitcoin_signature *remotesig, const struct bitcoin_signature *remotesig,
@@ -109,7 +110,8 @@ u8 *bitcoin_wscript_htlc_receive(const tal_t *ctx,
const struct pubkey *remotekey, const struct pubkey *remotekey,
const struct sha256 *payment_hash, const struct sha256 *payment_hash,
const struct pubkey *revocationkey, 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, u8 **bitcoin_witness_htlc_success_tx(const tal_t *ctx,
const struct bitcoin_signature *localsig, const struct bitcoin_signature *localsig,
const struct bitcoin_signature *remotesig, 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 pubkey *remotehtlckey,
const struct ripemd160 *payment_ripemd, const struct ripemd160 *payment_ripemd,
const struct pubkey *revocationkey, 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, u8 *bitcoin_wscript_htlc_receive_ripemd(const tal_t *ctx,
const struct abs_locktime *htlc_abstimeout, const struct abs_locktime *htlc_abstimeout,
const struct pubkey *localkey, const struct pubkey *localkey,
const struct pubkey *remotekey, const struct pubkey *remotekey,
const struct ripemd160 *payment_ripemd, const struct ripemd160 *payment_ripemd,
const struct pubkey *revocationkey, 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 */ /* BOLT #3 HTLC-success/HTLC-timeout output */
u8 *bitcoin_wscript_htlc_tx(const tal_t *ctx, 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); txs[i+1]->wtx->inputs[0].index);
msg = towire_hsmd_sign_remote_htlc_tx(NULL, txs[i + 1], wscript, msg = towire_hsmd_sign_remote_htlc_tx(NULL, txs[i + 1], wscript,
&peer->remote_per_commit, &peer->remote_per_commit,
channel_has(peer->channel, channel_has_anchors(peer->channel));
OPT_ANCHOR_OUTPUTS));
msg = hsm_req(tmpctx, take(msg)); msg = hsm_req(tmpctx, take(msg));
if (!fromwire_hsmd_sign_tx_reply(msg, &htlc_sigs[i])) 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. */ /* SIGHASH_ALL is implied. */
commit_sig.sighash_type = SIGHASH_ALL; commit_sig.sighash_type = SIGHASH_ALL;
htlc_sigs = unraw_sigs(tmpctx, raw_sigs, htlc_sigs = unraw_sigs(tmpctx, raw_sigs,
channel_has(peer->channel, OPT_ANCHOR_OUTPUTS)); channel_has_anchors(peer->channel));
txs = txs =
channel_txs(tmpctx, &htlc_map, NULL, channel_txs(tmpctx, &htlc_map, NULL,
@@ -3759,9 +3758,12 @@ static void init_channel(struct peer *peer)
peer->dev_fast_gossip = dev_fast_gossip; peer->dev_fast_gossip = dev_fast_gossip;
#endif #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_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 /* Keeping an array of pointers is better since it allows us to avoid
* extra allocations later. */ * extra allocations later. */

View File

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

View File

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

View File

@@ -243,8 +243,14 @@ static void add_htlcs(struct bitcoin_tx ***txs,
enum side side) enum side side)
{ {
struct bitcoin_outpoint outpoint; 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_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 */ /* Get txid of commitment transaction */
bitcoin_txid((*txs)[0], &outpoint.txid); bitcoin_txid((*txs)[0], &outpoint.txid);
@@ -261,27 +267,31 @@ static void add_htlcs(struct bitcoin_tx ***txs,
if (htlc_owner(htlc) == side) { if (htlc_owner(htlc) == side) {
ripemd160(&ripemd, htlc->rhash.u.u8, sizeof(htlc->rhash.u.u8)); ripemd160(&ripemd, htlc->rhash.u.u8, sizeof(htlc->rhash.u.u8));
wscript = htlc_offered_wscript(tmpctx, &ripemd, keyset, 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, tx = htlc_timeout_tx(*txs, chainparams, &outpoint,
wscript, wscript,
htlc->amount, htlc->amount,
htlc->expiry.locktime, htlc->expiry.locktime,
channel->config[!side].to_self_delay, channel->config[!side].to_self_delay,
feerate_per_kw, htlc_feerate_per_kw,
keyset, keyset,
option_anchor_outputs); option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
} else { } else {
ripemd160(&ripemd, htlc->rhash.u.u8, sizeof(htlc->rhash.u.u8)); ripemd160(&ripemd, htlc->rhash.u.u8, sizeof(htlc->rhash.u.u8));
wscript = htlc_received_wscript(tmpctx, &ripemd, wscript = htlc_received_wscript(tmpctx, &ripemd,
&htlc->expiry, keyset, &htlc->expiry, keyset,
option_anchor_outputs); option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
tx = htlc_success_tx(*txs, chainparams, &outpoint, tx = htlc_success_tx(*txs, chainparams, &outpoint,
wscript, wscript,
htlc->amount, htlc->amount,
channel->config[!side].to_self_delay, channel->config[!side].to_self_delay,
feerate_per_kw, htlc_feerate_per_kw,
keyset, keyset,
option_anchor_outputs); option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
} }
/* Append to array. */ /* 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, channel->view[side].owed[!side], committed, htlcmap, direct_outputs,
commitment_number ^ channel->commitment_number_obscurer, commitment_number ^ channel->commitment_number_obscurer,
channel_has(channel, OPT_ANCHOR_OUTPUTS), channel_has(channel, OPT_ANCHOR_OUTPUTS),
channel_has(channel, OPT_ANCHORS_ZERO_FEE_HTLC_TX),
side); side);
/* Set the remote/local pubkeys on the commitment tx psbt */ /* 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, static size_t num_untrimmed_htlcs(enum side side,
struct amount_sat dust_limit, struct amount_sat dust_limit,
u32 feerate, u32 feerate,
bool option_static_remotekey, bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx,
const struct htlc **committed, const struct htlc **committed,
const struct htlc **adding, const struct htlc **adding,
const struct htlc **removing) const struct htlc **removing)
{ {
return commit_tx_num_untrimmed(committed, feerate, dust_limit, 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, + 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, - 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, 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; struct amount_sat dust_limit = channel->config[side].dust_limit;
size_t untrimmed; size_t untrimmed;
bool option_anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS); 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, untrimmed = num_untrimmed_htlcs(side, dust_limit, feerate,
option_anchor_outputs, option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
committed, adding, removing); 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, 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; struct amount_sat dust_limit = channel->config[side].dust_limit;
bool option_anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS); 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); struct amount_msat trim_rmvd = AMOUNT_MSAT(0);
if (!commit_tx_amount_trimmed(committed, feerate, if (!commit_tx_amount_trimmed(committed, feerate,
dust_limit, dust_limit,
option_anchor_outputs, option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
side, trim_total)) side, trim_total))
return false; return false;
if (!commit_tx_amount_trimmed(adding, feerate, if (!commit_tx_amount_trimmed(adding, feerate,
dust_limit, dust_limit,
option_anchor_outputs, option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
side, trim_total)) side, trim_total))
return false; return false;
if (!commit_tx_amount_trimmed(removing, feerate, if (!commit_tx_amount_trimmed(removing, feerate,
dust_limit, dust_limit,
option_anchor_outputs, option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
side, &trim_rmvd)) side, &trim_rmvd))
return false; return false;
@@ -489,6 +515,7 @@ static bool local_opener_has_fee_headroom(const struct channel *channel,
size_t untrimmed; size_t untrimmed;
struct amount_sat fee; struct amount_sat fee;
bool option_anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS); 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); 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, untrimmed = num_untrimmed_htlcs(LOCAL, channel->config[LOCAL].dust_limit,
feerate, feerate,
option_anchor_outputs, option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
committed, adding, removing); committed, adding, removing);
/* Now, how much would it cost us if feerate increases 100% and we added /* Now, how much would it cost us if feerate increases 100% and we added
* another HTLC? */ * another HTLC? */
fee = commit_tx_base_fee(2 * feerate, untrimmed + 1, 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)) if (amount_msat_greater_eq_sat(remainder, fee))
return true; return true;
@@ -535,6 +564,7 @@ static enum channel_add_err add_htlc(struct channel *channel,
const struct channel_view *view; const struct channel_view *view;
size_t htlc_count; size_t htlc_count;
bool option_anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS); 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; u32 feerate, feerate_ceil;
htlc = tal(tmpctx, struct htlc); 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 * of 330 sats from the funder (either `to_local` or
* `to_remote`). * `to_remote`).
*/ */
if (option_anchor_outputs if ((option_anchor_outputs || option_anchors_zero_fee_htlc_tx)
&& channel->opener == sender && channel->opener == sender
&& !amount_msat_sub_sat(&remainder, remainder, AMOUNT_SAT(660))) && !amount_msat_sub_sat(&remainder, remainder, AMOUNT_SAT(660)))
return CHANNEL_ERR_CHANNEL_CAPACITY_EXCEEDED; return CHANNEL_ERR_CHANNEL_CAPACITY_EXCEEDED;
@@ -738,7 +768,7 @@ static enum channel_add_err add_htlc(struct channel *channel,
&remainder)) &remainder))
return CHANNEL_ERR_CHANNEL_CAPACITY_EXCEEDED; return CHANNEL_ERR_CHANNEL_CAPACITY_EXCEEDED;
if (option_anchor_outputs if ((option_anchor_outputs || option_anchors_zero_fee_htlc_tx)
&& channel->opener != sender && channel->opener != sender
&& !amount_msat_sub_sat(&remainder, remainder, AMOUNT_SAT(660))) && !amount_msat_sub_sat(&remainder, remainder, AMOUNT_SAT(660)))
return CHANNEL_ERR_CHANNEL_CAPACITY_EXCEEDED; return CHANNEL_ERR_CHANNEL_CAPACITY_EXCEEDED;
@@ -1167,6 +1197,7 @@ u32 approx_max_feerate(const struct channel *channel)
struct amount_sat avail; struct amount_sat avail;
const struct htlc **committed, **adding, **removing; const struct htlc **committed, **adding, **removing;
bool option_anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS); 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, gather_htlcs(tmpctx, channel, !channel->opener,
&committed, &removing, &adding); &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. */ /* Assume none are trimmed; this gives lower bound on feerate. */
num = tal_count(committed) + tal_count(adding) - tal_count(removing); 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 */ /* Available is their view */
avail = amount_msat_to_sat_round_down(channel->view[!channel->opener].owed[channel->opener]); 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 * of 330 sats from the funder (either `to_local` or
* `to_remote`). * `to_remote`).
*/ */
if (option_anchor_outputs if ((option_anchor_outputs || option_anchors_zero_fee_htlc_tx)
&& !amount_sat_sub(&avail, avail, AMOUNT_SAT(660))) { && !amount_sat_sub(&avail, avail, AMOUNT_SAT(660))) {
avail = AMOUNT_SAT(0); avail = AMOUNT_SAT(0);
} else { } else {
@@ -1236,22 +1267,27 @@ bool can_opener_afford_feerate(const struct channel *channel, u32 feerate_per_kw
size_t untrimmed; size_t untrimmed;
const struct htlc **committed, **adding, **removing; const struct htlc **committed, **adding, **removing;
bool option_anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS); 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, gather_htlcs(tmpctx, channel, !channel->opener,
&committed, &removing, &adding); &committed, &removing, &adding);
untrimmed = commit_tx_num_untrimmed(committed, feerate_per_kw, dust_limit, untrimmed = commit_tx_num_untrimmed(committed, feerate_per_kw, dust_limit,
option_anchor_outputs, option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
!channel->opener) !channel->opener)
+ commit_tx_num_untrimmed(adding, feerate_per_kw, dust_limit, + commit_tx_num_untrimmed(adding, feerate_per_kw, dust_limit,
option_anchor_outputs, option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
!channel->opener) !channel->opener)
- commit_tx_num_untrimmed(removing, feerate_per_kw, dust_limit, - commit_tx_num_untrimmed(removing, feerate_per_kw, dust_limit,
option_anchor_outputs, option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
!channel->opener); !channel->opener);
fee = commit_tx_base_fee(feerate_per_kw, untrimmed, fee = commit_tx_base_fee(feerate_per_kw, untrimmed,
option_anchor_outputs); option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
/* BOLT #3: /* BOLT #3:
* If `option_anchors` applies to the commitment * 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 * of 330 sats from the funder (either `to_local` or
* `to_remote`). * `to_remote`).
*/ */
if (option_anchor_outputs if ((option_anchor_outputs || option_anchors_zero_fee_htlc_tx)
&& !amount_sat_add(&fee, fee, AMOUNT_SAT(660))) && !amount_sat_add(&fee, fee, AMOUNT_SAT(660)))
status_failed(STATUS_FAIL_INTERNAL_ERROR, status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Cannot add 660 sats to %s for anchor", "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_htlckey,
const struct pubkey *remote_revocation_key, const struct pubkey *remote_revocation_key,
u32 feerate_per_kw, u32 feerate_per_kw,
bool option_anchor_outputs) bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx)
{ {
size_t i, n; size_t i, n;
struct bitcoin_outpoint outpoint; struct bitcoin_outpoint outpoint;
@@ -291,14 +292,17 @@ static void report_htlcs(const struct bitcoin_tx *tx,
remote_htlckey, remote_htlckey,
&htlc->rhash, &htlc->rhash,
remote_revocation_key, 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, htlc_tx[i] = htlc_timeout_tx(htlc_tx, tx->chainparams,
&outpoint, wscript[i], &outpoint, wscript[i],
htlc->amount, htlc->amount,
htlc->expiry.locktime, htlc->expiry.locktime,
to_self_delay, to_self_delay,
feerate_per_kw, feerate_per_kw,
&keyset, option_anchor_outputs); &keyset,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
} else { } else {
wscript[i] = bitcoin_wscript_htlc_receive(tmpctx, wscript[i] = bitcoin_wscript_htlc_receive(tmpctx,
&htlc->expiry, &htlc->expiry,
@@ -306,14 +310,16 @@ static void report_htlcs(const struct bitcoin_tx *tx,
remote_htlckey, remote_htlckey,
&htlc->rhash, &htlc->rhash,
remote_revocation_key, 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, htlc_tx[i] = htlc_success_tx(htlc_tx, tx->chainparams,
&outpoint, wscript[i], &outpoint, wscript[i],
htlc->amount, htlc->amount,
to_self_delay, to_self_delay,
feerate_per_kw, feerate_per_kw,
&keyset, &keyset,
option_anchor_outputs); option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
} }
sign_tx_input(htlc_tx[i], 0, sign_tx_input(htlc_tx[i], 0,
NULL, NULL,
@@ -344,7 +350,8 @@ static void report_htlcs(const struct bitcoin_tx *tx,
remote_revocation_key, remote_revocation_key,
&localhtlcsig, &localhtlcsig,
&remotehtlcsig[i], &remotehtlcsig[i],
option_anchor_outputs); option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
} else { } else {
htlc_success_tx_add_witness(htlc_tx[i], htlc_success_tx_add_witness(htlc_tx[i],
&htlc->expiry, &htlc->expiry,
@@ -354,7 +361,8 @@ static void report_htlcs(const struct bitcoin_tx *tx,
&remotehtlcsig[i], &remotehtlcsig[i],
htlc->r, htlc->r,
remote_revocation_key, remote_revocation_key,
option_anchor_outputs); option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
} }
printf("htlc_%s_tx (htlc #%"PRIu64"): %s\n", printf("htlc_%s_tx (htlc #%"PRIu64"): %s\n",
htlc_owner(htlc) == LOCAL ? "timeout" : "success", htlc_owner(htlc) == LOCAL ? "timeout" : "success",
@@ -380,6 +388,7 @@ static void report(struct bitcoin_tx *tx,
const struct pubkey *remote_revocation_key, const struct pubkey *remote_revocation_key,
u32 feerate_per_kw, u32 feerate_per_kw,
bool option_anchor_outputs, bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx,
const struct htlc **htlc_map, const struct htlc **htlc_map,
size_t total_htlcs) size_t total_htlcs)
{ {
@@ -425,7 +434,8 @@ static void report(struct bitcoin_tx *tx,
remotekey, remote_htlckey, remotekey, remote_htlckey,
remote_revocation_key, remote_revocation_key,
feerate_per_kw, feerate_per_kw,
option_anchor_outputs); option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
} }
#ifdef DEBUG #ifdef DEBUG
@@ -530,6 +540,7 @@ int main(int argc, const char *argv[])
struct amount_msat to_local, to_remote; struct amount_msat to_local, to_remote;
const struct htlc **htlcs, **htlc_map, **htlc_map2, **inv_htlcs; const struct htlc **htlcs, **htlc_map, **htlc_map2, **inv_htlcs;
bool option_anchor_outputs = false; bool option_anchor_outputs = false;
bool option_anchors_zero_fee_htlc_tx = false;
bool option_static_remotekey = false; bool option_static_remotekey = false;
/* Allow us to check static-remotekey BOLT 3 vectors, too */ /* Allow us to check static-remotekey BOLT 3 vectors, too */
@@ -814,6 +825,7 @@ int main(int argc, const char *argv[])
to_remote, to_remote,
NULL, &htlc_map, NULL, commitment_number ^ cn_obscurer, NULL, &htlc_map, NULL, commitment_number ^ cn_obscurer,
option_anchor_outputs, option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
LOCAL); LOCAL);
print_superverbose = false; print_superverbose = false;
tx2 = commit_tx(tmpctx, tx2 = commit_tx(tmpctx,
@@ -830,6 +842,7 @@ int main(int argc, const char *argv[])
to_remote, to_remote,
NULL, &htlc_map2, NULL, commitment_number ^ cn_obscurer, NULL, &htlc_map2, NULL, commitment_number ^ cn_obscurer,
option_anchor_outputs, option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
REMOTE); REMOTE);
tx_must_be_eq(tx, tx2); tx_must_be_eq(tx, tx2);
report(tx, wscript, &x_remote_funding_privkey, &remote_funding_pubkey, report(tx, wscript, &x_remote_funding_privkey, &remote_funding_pubkey,
@@ -845,6 +858,7 @@ int main(int argc, const char *argv[])
&remote_revocation_key, &remote_revocation_key,
feerate_per_kw, feerate_per_kw,
option_anchor_outputs, option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
htlc_map, htlc_map,
0); 0);
@@ -880,6 +894,7 @@ int main(int argc, const char *argv[])
to_remote, to_remote,
htlcs, &htlc_map, NULL, commitment_number ^ cn_obscurer, htlcs, &htlc_map, NULL, commitment_number ^ cn_obscurer,
option_anchor_outputs, option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
LOCAL); LOCAL);
print_superverbose = false; print_superverbose = false;
tx2 = commit_tx(tmpctx, tx2 = commit_tx(tmpctx,
@@ -897,6 +912,7 @@ int main(int argc, const char *argv[])
inv_htlcs, &htlc_map2, NULL, inv_htlcs, &htlc_map2, NULL,
commitment_number ^ cn_obscurer, commitment_number ^ cn_obscurer,
option_anchor_outputs, option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
REMOTE); REMOTE);
tx_must_be_eq(tx, tx2); tx_must_be_eq(tx, tx2);
report(tx, wscript, &x_remote_funding_privkey, &remote_funding_pubkey, report(tx, wscript, &x_remote_funding_privkey, &remote_funding_pubkey,
@@ -912,6 +928,7 @@ int main(int argc, const char *argv[])
&remote_revocation_key, &remote_revocation_key,
feerate_per_kw, feerate_per_kw,
option_anchor_outputs, option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
htlc_map, htlc_map,
tal_count(htlcs)); tal_count(htlcs));
@@ -935,6 +952,7 @@ int main(int argc, const char *argv[])
htlcs, &htlc_map, NULL, htlcs, &htlc_map, NULL,
commitment_number ^ cn_obscurer, commitment_number ^ cn_obscurer,
option_anchor_outputs, option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
LOCAL); LOCAL);
/* This is what it would look like for peer generating it! */ /* This is what it would look like for peer generating it! */
tx2 = commit_tx(tmpctx, tx2 = commit_tx(tmpctx,
@@ -952,6 +970,7 @@ int main(int argc, const char *argv[])
inv_htlcs, &htlc_map2, NULL, inv_htlcs, &htlc_map2, NULL,
commitment_number ^ cn_obscurer, commitment_number ^ cn_obscurer,
option_anchor_outputs, option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
REMOTE); REMOTE);
tx_must_be_eq(newtx, tx2); tx_must_be_eq(newtx, tx2);
#ifdef DEBUG #ifdef DEBUG
@@ -995,6 +1014,7 @@ int main(int argc, const char *argv[])
htlcs, &htlc_map, NULL, htlcs, &htlc_map, NULL,
commitment_number ^ cn_obscurer, commitment_number ^ cn_obscurer,
option_anchor_outputs, option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
LOCAL); LOCAL);
report(tx, wscript, report(tx, wscript,
&x_remote_funding_privkey, &remote_funding_pubkey, &x_remote_funding_privkey, &remote_funding_pubkey,
@@ -1010,6 +1030,7 @@ int main(int argc, const char *argv[])
&remote_revocation_key, &remote_revocation_key,
feerate_per_kw-1, feerate_per_kw-1,
option_anchor_outputs, option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
htlc_map, htlc_map,
tal_count(htlcs)); tal_count(htlcs));
@@ -1045,6 +1066,7 @@ int main(int argc, const char *argv[])
htlcs, &htlc_map, NULL, htlcs, &htlc_map, NULL,
commitment_number ^ cn_obscurer, commitment_number ^ cn_obscurer,
option_anchor_outputs, option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
LOCAL); LOCAL);
report(newtx, wscript, report(newtx, wscript,
&x_remote_funding_privkey, &remote_funding_pubkey, &x_remote_funding_privkey, &remote_funding_pubkey,
@@ -1060,6 +1082,7 @@ int main(int argc, const char *argv[])
&remote_revocation_key, &remote_revocation_key,
feerate_per_kw, feerate_per_kw,
option_anchor_outputs, option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
htlc_map, htlc_map,
tal_count(htlcs)); tal_count(htlcs));
@@ -1074,7 +1097,8 @@ int main(int argc, const char *argv[])
for (;;) { for (;;) {
struct amount_sat base_fee struct amount_sat base_fee
= commit_tx_base_fee(feerate_per_kw, 0, = commit_tx_base_fee(feerate_per_kw, 0,
option_anchor_outputs); option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
/* BOLT #3: /* BOLT #3:
* If `option_anchors` applies to the commitment * 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 * of 330 sats from the funder (either `to_local` or
* `to_remote`). * `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))) && !amount_sat_add(&base_fee, base_fee, AMOUNT_SAT(660)))
abort(); abort();
@@ -1121,6 +1145,7 @@ int main(int argc, const char *argv[])
htlcs, &htlc_map, NULL, htlcs, &htlc_map, NULL,
commitment_number ^ cn_obscurer, commitment_number ^ cn_obscurer,
option_anchor_outputs, option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
LOCAL); LOCAL);
report(tx, wscript, report(tx, wscript,
&x_remote_funding_privkey, &remote_funding_pubkey, &x_remote_funding_privkey, &remote_funding_pubkey,
@@ -1136,6 +1161,7 @@ int main(int argc, const char *argv[])
&remote_revocation_key, &remote_revocation_key,
feerate_per_kw, feerate_per_kw,
option_anchor_outputs, option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
htlc_map, htlc_map,
tal_count(htlcs)); tal_count(htlcs));
break; break;
@@ -1176,6 +1202,7 @@ int main(int argc, const char *argv[])
to_remote, to_remote,
htlcs, &htlc_map, NULL, commitment_number ^ cn_obscurer, htlcs, &htlc_map, NULL, commitment_number ^ cn_obscurer,
option_anchor_outputs, option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
LOCAL); LOCAL);
print_superverbose = false; print_superverbose = false;
tx2 = commit_tx(tmpctx, tx2 = commit_tx(tmpctx,
@@ -1193,6 +1220,7 @@ int main(int argc, const char *argv[])
inv_htlcs, &htlc_map2, NULL, inv_htlcs, &htlc_map2, NULL,
commitment_number ^ cn_obscurer, commitment_number ^ cn_obscurer,
option_anchor_outputs, option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
REMOTE); REMOTE);
tx_must_be_eq(tx, tx2); tx_must_be_eq(tx, tx2);
report(tx, wscript, &x_remote_funding_privkey, &remote_funding_pubkey, report(tx, wscript, &x_remote_funding_privkey, &remote_funding_pubkey,
@@ -1208,6 +1236,7 @@ int main(int argc, const char *argv[])
&remote_revocation_key, &remote_revocation_key,
feerate_per_kw, feerate_per_kw,
option_anchor_outputs, option_anchor_outputs,
option_anchors_zero_fee_htlc_tx,
htlc_map, htlc_map,
tal_count(htlcs)); tal_count(htlcs));
common_shutdown(); common_shutdown();

View File

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

View File

@@ -8,7 +8,8 @@ bool htlc_is_trimmed(enum side htlc_owner,
u32 feerate_per_kw, u32 feerate_per_kw,
struct amount_sat dust_limit, struct amount_sat dust_limit,
enum side side, 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; struct amount_sat htlc_fee, htlc_min;
@@ -24,7 +25,8 @@ bool htlc_is_trimmed(enum side htlc_owner,
*/ */
if (htlc_owner == side) if (htlc_owner == side)
htlc_fee = htlc_timeout_fee(feerate_per_kw, htlc_fee = htlc_timeout_fee(feerate_per_kw,
option_anchor_outputs); option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
/* BOLT #3: /* BOLT #3:
* *
* - for every received HTLC: * - for every received HTLC:
@@ -36,7 +38,8 @@ bool htlc_is_trimmed(enum side htlc_owner,
*/ */
else else
htlc_fee = htlc_success_fee(feerate_per_kw, 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 these overflow, it implies htlc must be less. */
if (!amount_sat_add(&htlc_min, dust_limit, htlc_fee)) 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, u32 feerate_per_kw,
struct amount_sat dust_limit, struct amount_sat dust_limit,
enum side side, 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 /* Calculate the our htlc-trimming buffer feerate
* (max(25%, 10s/vbyte) above feerate_per_kw) */ * (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, const u8 *htlc_tx_wscript,
struct amount_sat htlc_fee, struct amount_sat htlc_fee,
u32 locktime, u32 locktime,
bool option_anchor_outputs) bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx)
{ {
/* BOLT #3: /* BOLT #3:
* * locktime: `0` for HTLC-success, `cltv_expiry` for HTLC-timeout * * 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`) * * `txin[0]` sequence: `0` (set to `1` for `option_anchors`)
*/ */
bitcoin_tx_add_input(tx, commit, 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); NULL, amount, NULL, commit_wscript);
/* BOLT #3: /* 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 * * `txout[0]` script: version-0 P2WSH with witness script as shown
* below * below
*/ */
/* Note: for option_anchors_zero_fee_htlc_tx, htlc_fee is 0 */
if (!amount_sat_sub(&amount, amount, htlc_fee)) if (!amount_sat_sub(&amount, amount, htlc_fee))
return tal_free(tx); return tal_free(tx);
@@ -74,7 +76,8 @@ struct bitcoin_tx *htlc_success_tx(const tal_t *ctx,
u16 to_self_delay, u16 to_self_delay,
u32 feerate_per_kw, u32 feerate_per_kw,
const struct keyset *keyset, const struct keyset *keyset,
bool option_anchor_outputs) bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx)
{ {
const u8 *htlc_wscript; 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), amount_msat_to_sat_round_down(htlc_msatoshi),
htlc_wscript, htlc_wscript,
htlc_success_fee(feerate_per_kw, htlc_success_fee(feerate_per_kw,
option_anchor_outputs), option_anchor_outputs,
option_anchors_zero_fee_htlc_tx),
0, 0,
option_anchor_outputs); option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
} }
/* Fill in the witness for HTLC-success tx produced above. */ /* 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 bitcoin_signature *remotehtlcsig,
const struct preimage *payment_preimage, const struct preimage *payment_preimage,
const struct pubkey *revocationkey, const struct pubkey *revocationkey,
bool option_anchor_outputs) bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx)
{ {
struct sha256 hash; struct sha256 hash;
u8 *wscript, **witness; u8 *wscript, **witness;
@@ -114,7 +120,8 @@ void htlc_success_tx_add_witness(struct bitcoin_tx *htlc_success,
htlc_abstimeout, htlc_abstimeout,
localhtlckey, remotehtlckey, localhtlckey, remotehtlckey,
&hash, revocationkey, &hash, revocationkey,
option_anchor_outputs); option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
witness = bitcoin_witness_htlc_success_tx(htlc_success, witness = bitcoin_witness_htlc_success_tx(htlc_success,
localhtlcsig, remotehtlcsig, localhtlcsig, remotehtlcsig,
@@ -132,7 +139,8 @@ struct bitcoin_tx *htlc_timeout_tx(const tal_t *ctx,
u16 to_self_delay, u16 to_self_delay,
u32 feerate_per_kw, u32 feerate_per_kw,
const struct keyset *keyset, const struct keyset *keyset,
bool option_anchor_outputs) bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx)
{ {
const u8 *htlc_wscript; 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), amount_msat_to_sat_round_down(htlc_msatoshi),
htlc_wscript, htlc_wscript,
htlc_timeout_fee(feerate_per_kw, htlc_timeout_fee(feerate_per_kw,
option_anchor_outputs), option_anchor_outputs,
option_anchors_zero_fee_htlc_tx),
cltv_expiry, cltv_expiry,
option_anchor_outputs); option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
} }
/* Fill in the witness for HTLC-timeout tx produced above. */ /* 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 pubkey *revocationkey,
const struct bitcoin_signature *localhtlcsig, const struct bitcoin_signature *localhtlcsig,
const struct bitcoin_signature *remotehtlcsig, const struct bitcoin_signature *remotehtlcsig,
bool option_anchor_outputs) bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx)
{ {
u8 **witness; u8 **witness;
u8 *wscript = bitcoin_wscript_htlc_offer(htlc_timeout, u8 *wscript = bitcoin_wscript_htlc_offer(htlc_timeout,
localhtlckey, remotehtlckey, localhtlckey, remotehtlckey,
payment_hash, revocationkey, payment_hash, revocationkey,
option_anchor_outputs); option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
witness = bitcoin_witness_htlc_timeout_tx(htlc_timeout, localhtlcsig, witness = bitcoin_witness_htlc_timeout_tx(htlc_timeout, localhtlcsig,
remotehtlcsig, wscript); 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, u8 *htlc_offered_wscript(const tal_t *ctx,
const struct ripemd160 *ripemd, const struct ripemd160 *ripemd,
const struct keyset *keyset, 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, return bitcoin_wscript_htlc_offer_ripemd160(ctx,
&keyset->self_htlc_key, &keyset->self_htlc_key,
&keyset->other_htlc_key, &keyset->other_htlc_key,
ripemd, ripemd,
&keyset->self_revocation_key, &keyset->self_revocation_key,
option_anchor_outputs); option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
} }
u8 *htlc_received_wscript(const tal_t *ctx, u8 *htlc_received_wscript(const tal_t *ctx,
const struct ripemd160 *ripemd, const struct ripemd160 *ripemd,
const struct abs_locktime *expiry, const struct abs_locktime *expiry,
const struct keyset *keyset, 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, return bitcoin_wscript_htlc_receive_ripemd(ctx,
expiry, expiry,
@@ -200,5 +215,6 @@ u8 *htlc_received_wscript(const tal_t *ctx,
&keyset->other_htlc_key, &keyset->other_htlc_key,
ripemd, ripemd,
&keyset->self_revocation_key, &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; struct ripemd160;
static inline struct amount_sat htlc_timeout_fee(u32 feerate_per_kw, 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: /* BOLT #3:
* *
* The fee for an HTLC-timeout transaction: * 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: * - Otherwise, MUST be calculated to match:
* 1. Multiply `feerate_per_kw` by 663 (666 if `option_anchor_outputs` * 1. Multiply `feerate_per_kw` by 663 (666 if `option_anchor_outputs`
* applies) and divide by 1000 (rounding down). * applies) and divide by 1000 (rounding down).
*/ */
u32 base; u32 base;
if (option_anchors_zero_fee_htlc_tx)
return AMOUNT_SAT(0);
if (option_anchor_outputs) if (option_anchor_outputs)
base = 666; base = 666;
else 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, 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: /* BOLT #3:
* *
* The fee for an HTLC-success transaction: * 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: * - Otherwise, MUST be calculated to match:
* 1. Multiply `feerate_per_kw` by 703 (706 if `option_anchor_outputs` * 1. Multiply `feerate_per_kw` by 703 (706 if `option_anchor_outputs`
* applies) and divide by 1000 (rounding down). * applies) and divide by 1000 (rounding down).
*/ */
u32 base; u32 base;
if (option_anchors_zero_fee_htlc_tx)
return AMOUNT_SAT(0);
if (option_anchor_outputs) if (option_anchor_outputs)
base = 706; base = 706;
else else
@@ -63,7 +75,8 @@ struct bitcoin_tx *htlc_success_tx(const tal_t *ctx,
u16 to_self_delay, u16 to_self_delay,
u32 feerate_per_kw, u32 feerate_per_kw,
const struct keyset *keyset, 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. */ /* Fill in the witness for HTLC-success tx produced above. */
void htlc_success_tx_add_witness(struct bitcoin_tx *htlc_success, 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 bitcoin_signature *remotesig,
const struct preimage *payment_preimage, const struct preimage *payment_preimage,
const struct pubkey *revocationkey, 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 /* Create HTLC-timeout tx to spend an offered HTLC commitment tx
* output; doesn't fill in input witness. */ * 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, u16 to_self_delay,
u32 feerate_per_kw, u32 feerate_per_kw,
const struct keyset *keyset, 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. */ /* Fill in the witness for HTLC-timeout tx produced above. */
void htlc_timeout_tx_add_witness(struct bitcoin_tx *htlc_timeout, 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 pubkey *revocationkey,
const struct bitcoin_signature *localsig, const struct bitcoin_signature *localsig,
const struct bitcoin_signature *remotesig, 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: /* Generate the witness script for an HTLC the other side offered:
* scriptpubkey_p2wsh(ctx, wscript) gives the scriptpubkey */ * 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 ripemd160 *ripemd,
const struct abs_locktime *expiry, const struct abs_locktime *expiry,
const struct keyset *keyset, 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: /* Generate the witness script for an HTLC this side offered:
* scriptpubkey_p2wsh(ctx, wscript) gives the scriptpubkey */ * scriptpubkey_p2wsh(ctx, wscript) gives the scriptpubkey */
u8 *htlc_offered_wscript(const tal_t *ctx, u8 *htlc_offered_wscript(const tal_t *ctx,
const struct ripemd160 *ripemd, const struct ripemd160 *ripemd,
const struct keyset *keyset, const struct keyset *keyset,
bool option_anchor_outputs); bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx);
/* Low-level HTLC tx creator */ /* Low-level HTLC tx creator */
struct bitcoin_tx *htlc_tx(const tal_t *ctx, 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, const u8 *htlc_tx_wscript,
struct amount_sat htlc_fee, struct amount_sat htlc_fee,
u32 locktime, u32 locktime,
bool option_anchor_outputs); bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx);
#endif /* LIGHTNING_COMMON_HTLC_TX_H */ #endif /* LIGHTNING_COMMON_HTLC_TX_H */

View File

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

View File

@@ -88,6 +88,7 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx,
enum side side, enum side side,
u32 csv_lock, u32 csv_lock,
bool option_anchor_outputs, bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx,
char** err_reason) char** err_reason)
{ {
struct amount_sat base_fee; struct amount_sat base_fee;
@@ -122,15 +123,16 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx,
* fee](#fee-calculation). * fee](#fee-calculation).
*/ */
base_fee = commit_tx_base_fee(feerate_per_kw, untrimmed, base_fee = commit_tx_base_fee(feerate_per_kw, untrimmed,
option_anchor_outputs); option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
/* BOLT: /* BOLT #3:
* If `option_anchor_outputs` applies to the commitment * If `option_anchors` applies to the commitment
* transaction, also subtract two times the fixed anchor size * transaction, also subtract two times the fixed anchor size
* of 330 sats from the funder (either `to_local` or * of 330 sats from the funder (either `to_local` or
* `to_remote`). * `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))) { && !amount_sat_add(&base_fee, base_fee, AMOUNT_SAT(660))) {
*err_reason = "Funder cannot afford anchor outputs"; *err_reason = "Funder cannot afford anchor outputs";
return NULL; return NULL;
@@ -246,7 +248,7 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx,
u8 *redeem; u8 *redeem;
amount = amount_msat_to_sat_round_down(other_pay); 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, redeem = bitcoin_wscript_to_remote_anchored(tmpctx,
&keyset->other_payment_key, &keyset->other_payment_key,
(!side) == lessor ? csv_lock : 1); (!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 * * if `to_remote` exists or there are untrimmed HTLCs, add a
* [`to_remote_anchor` output] * [`to_remote_anchor` output]
*/ */
if (option_anchor_outputs) { if (option_anchor_outputs || option_anchors_zero_fee_htlc_tx) {
if (to_local || untrimmed != 0) { if (to_local || untrimmed != 0) {
tx_add_anchor_output(tx, &funding_key[side]); tx_add_anchor_output(tx, &funding_key[side]);
output_order[n] = NULL; 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 */ /* The base weight of a commitment tx */
static inline size_t commit_tx_base_weight(size_t num_untrimmed_htlcs, 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 weight;
size_t num_outputs; 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: * - MUST be calculated to match:
* 1. Start with `weight` = 724 (1124 if `option_anchors` applies). * 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; weight = 1124;
num_outputs = 4; num_outputs = 4;
} else { } 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 */ /* 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, static inline struct amount_sat commit_tx_base_fee(u32 feerate_per_kw,
size_t num_untrimmed_htlcs, 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, return amount_tx_fee(feerate_per_kw,
commit_tx_base_weight(num_untrimmed_htlcs, 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, enum side side,
u32 csv_lock, u32 csv_lock,
bool option_anchor_outputs, bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx,
char** err_reason); char** err_reason);
/* try_subtract_fee - take away this fee from the opener (and return true), or all if insufficient (and return false). */ /* 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); towire_bool(pptr, utxo->close_info->commitment_point != NULL);
if (utxo->close_info->commitment_point) if (utxo->close_info->commitment_point)
towire_pubkey(pptr, 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); 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); utxo->close_info->commitment_point);
} else } else
utxo->close_info->commitment_point = NULL; utxo->close_info->commitment_point = NULL;
utxo->close_info->option_anchor_outputs utxo->close_info->option_anchors
= fromwire_bool(ptr, max); = fromwire_bool(ptr, max);
utxo->close_info->csv = fromwire_u32(ptr, max); utxo->close_info->csv = fromwire_u32(ptr, max);
} else { } else {

View File

@@ -11,7 +11,7 @@ struct ext_key;
struct unilateral_close_info { struct unilateral_close_info {
u64 channel_id; u64 channel_id;
struct node_id peer_id; struct node_id peer_id;
bool option_anchor_outputs; bool option_anchors;
/* NULL if this is an option_static_remotekey commitment */ /* NULL if this is an option_static_remotekey commitment */
struct pubkey *commitment_point; struct pubkey *commitment_point;
u32 csv; u32 csv;
@@ -71,8 +71,11 @@ static inline bool utxo_is_csv_locked(const struct utxo *utxo, u32 current_heigh
{ {
if (!utxo->close_info) if (!utxo->close_info)
return false; return false;
/* All close outputs are csv locked for option_anchor_outputs */ /* BOLT #3:
if (!utxo->blockheight && utxo->close_info->option_anchor_outputs) * 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; return true;
assert(*utxo->blockheight + utxo->close_info->csv > *utxo->blockheight); assert(*utxo->blockheight + utxo->close_info->csv > *utxo->blockheight);
return *utxo->blockheight + utxo->close_info->csv > current_height; return *utxo->blockheight + utxo->close_info->csv > current_height;

View File

@@ -111,7 +111,8 @@ int main(int argc, char *argv[])
argnum++; argnum++;
fee = commit_tx_base_fee(feerate_per_kw, 0, fee = commit_tx_base_fee(feerate_per_kw, 0,
option_anchor_outputs); option_anchor_outputs,
false);
/* BOLT #3: /* BOLT #3:
* If `option_anchors` applies to the commitment * If `option_anchors` applies to the commitment
* transaction, also subtract two times the fixed anchor size * 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); psbt_input_add_pubkey(psbt, j, &pubkey);
/* It's actually a P2WSH in this case. */ /* 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 const u8 *wscript
= bitcoin_wscript_to_remote_anchored(tmpctx, = bitcoin_wscript_to_remote_anchored(tmpctx,
&pubkey, &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); struct anchor_details *adet = tal(ctx, struct anchor_details);
/* If we don't have an anchor, we can't do anything. */ /* 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); return tal_free(adet);
if (!hsm_capable(ld, WIRE_HSMD_SIGN_ANCHORSPEND)) { 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... */ /* It actually is negotiated per-channel... */
bool anchor_outputs bool anchor_outputs
= feature_offered(cmd->ld->our_features->bits[INIT_FEATURE], = 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"); json_object_start(response, "onchain_fee_estimates");
/* eg 020000000001016f51de645a47baa49a636b8ec974c28bdff0ac9151c0f4eda2dbe3b41dbe711d000000001716001401fad90abcd66697e2592164722de4a95ebee165ffffffff0240420f00000000002200205b8cd3b914cf67cdd8fa6273c930353dd36476734fbd962102c2df53b90880cdb73f890000000000160014c2ccab171c2a5be9dab52ec41b825863024c54660248304502210088f65e054dbc2d8f679de3e40150069854863efa4a45103b2bb63d060322f94702200d3ae8923924a458cffb0b7360179790830027bb6b29715ba03e12fc22365de1012103d745445c9362665f22e0d96e9e766f273f3260dea39c8a76bfa05dd2684ddccf00000000 == weight 702 */ /* eg 020000000001016f51de645a47baa49a636b8ec974c28bdff0ac9151c0f4eda2dbe3b41dbe711d000000001716001401fad90abcd66697e2592164722de4a95ebee165ffffffff0240420f00000000002200205b8cd3b914cf67cdd8fa6273c930353dd36476734fbd962102c2df53b90880cdb73f890000000000160014c2ccab171c2a5be9dab52ec41b825863024c54660248304502210088f65e054dbc2d8f679de3e40150069854863efa4a45103b2bb63d060322f94702200d3ae8923924a458cffb0b7360179790830027bb6b29715ba03e12fc22365de1012103d745445c9362665f22e0d96e9e766f273f3260dea39c8a76bfa05dd2684ddccf00000000 == weight 702 */
@@ -773,10 +775,10 @@ static struct command_result *json_feerates(struct command *cmd,
json_add_u64(response, "htlc_timeout_satoshis", json_add_u64(response, "htlc_timeout_satoshis",
htlc_timeout_fee(htlc_resolution_feerate(cmd->ld->topology), 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", json_add_u64(response, "htlc_success_satoshis",
htlc_success_fee(htlc_resolution_feerate(cmd->ld->topology), htlc_success_fee(htlc_resolution_feerate(cmd->ld->topology),
false).satoshis /* Raw: estimate */); false, false).satoshis /* Raw: estimate */);
json_object_end(response); 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; struct lightningd *ld = channel->peer->ld;
u32 final_commit_feerate; u32 final_commit_feerate;
bool option_anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS); 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]) { if (!channel->shutdown_scriptpubkey[REMOTE]) {
channel_internal_error(channel, 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, final_commit_feerate = get_feerate(channel->fee_states,
channel->opener, LOCAL); channel->opener, LOCAL);
feelimit = commit_tx_base_fee(final_commit_feerate, 0, 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. */ /* If we can't determine feerate, start at half unilateral feerate. */
feerate = mutual_close_feerate(ld->topology); 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 /* We use a feerate if anchor_outputs, otherwise max fee is set by
* the final unilateral. */ * the final unilateral. */
if (option_anchor_outputs) { if (option_anchor_outputs || option_anchors_zero_fee_htlc_tx) {
max_feerate = tal(tmpctx, u32); max_feerate = tal(tmpctx, u32);
/* Aim for reasonable max, but use final if we don't know. */ /* Aim for reasonable max, but use final if we don't know. */
*max_feerate = unilateral_feerate(ld->topology, false); *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 == 50
&& channel->closing_fee_negotiation_step_unit == CLOSING_FEE_NEGOTIATION_STEP_UNIT_PERCENTAGE) && channel->closing_fee_negotiation_step_unit == CLOSING_FEE_NEGOTIATION_STEP_UNIT_PERCENTAGE)
/* Always use quickclose with anchors */ /* Always use quickclose with anchors */
|| option_anchor_outputs, || option_anchor_outputs
|| option_anchors_zero_fee_htlc_tx,
channel->shutdown_wrong_funding); channel->shutdown_wrong_funding);
/* We don't expect a response: it will give us feedback on /* 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)) OPT_ANCHOR_OUTPUTS))
json_add_string(response, NULL, "option_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_array_end(response);
json_object_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 bitcoin_tx *tx,
const struct onchain_signing_info *info) 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); assert(info->msgtype == WIRE_ONCHAIND_SPEND_HTLC_SUCCESS);
return towire_hsmd_sign_any_local_htlc_tx(ctx, 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 bitcoin_tx *tx,
const struct onchain_signing_info *info) 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); assert(info->msgtype == WIRE_ONCHAIND_SPEND_HTLC_TIMEOUT);
return towire_hsmd_sign_any_local_htlc_tx(ctx, 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 bitcoin_tx *tx,
const struct onchain_signing_info *info) 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); assert(info->msgtype == WIRE_ONCHAIND_SPEND_FULFILL);
return towire_hsmd_sign_any_remote_htlc_to_us(ctx, 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 bitcoin_tx *tx,
const struct onchain_signing_info *info) 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); assert(info->msgtype == WIRE_ONCHAIND_SPEND_HTLC_EXPIRED);
return towire_hsmd_sign_any_remote_htlc_to_us(ctx, 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; struct lightningd *ld = channel->peer->ld;
/* We can't do much without anchor outputs (we could CPFP?) */ /* 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; return true;
/* Note that we can have UTXOs taken from us if there are a lot of /* 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 amount_sat out_sats;
struct preimage preimage; struct preimage preimage;
u64 htlc_id; 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 = new_signing_info(msg, channel, WIRE_ONCHAIND_SPEND_FULFILL);
info->minblock = 0; info->minblock = 0;
@@ -1209,7 +1209,8 @@ static void handle_onchaind_spend_htlc_success(struct channel *channel,
u8 **witness; u8 **witness;
struct bitcoin_signature sig; struct bitcoin_signature sig;
const struct onchain_witness_element **welements; 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 = new_signing_info(msg, channel, WIRE_ONCHAIND_SPEND_HTLC_SUCCESS);
info->minblock = 0; 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 * * locktime: `0` for HTLC-success, `cltv_expiry` for HTLC-timeout
*/ */
tx = htlc_tx(NULL, chainparams, &out, info->wscript, out_sats, htlc_wscript, fee, 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); tal_free(htlc_wscript);
if (!tx) { if (!tx) {
/* Can only happen if fee > out_sats */ /* Can only happen if fee > out_sats */
@@ -1289,7 +1290,8 @@ static void handle_onchaind_spend_htlc_timeout(struct channel *channel,
u8 **witness; u8 **witness;
struct bitcoin_signature sig; struct bitcoin_signature sig;
const struct onchain_witness_element **welements; 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); 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 * * locktime: `0` for HTLC-success, `cltv_expiry` for HTLC-timeout
*/ */
tx = htlc_tx(NULL, chainparams, &out, info->wscript, out_sats, htlc_wscript, fee, 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); tal_free(htlc_wscript);
if (!tx) { if (!tx) {
/* Can only happen if fee > out_sats */ /* 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; struct amount_sat out_sats;
u64 htlc_id; u64 htlc_id;
u32 cltv_expiry; 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); 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, uc->peer->their_features,
OPT_ANCHOR_OUTPUTS)) OPT_ANCHOR_OUTPUTS))
json_add_string(response, NULL, "option_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_array_end(response);
json_object_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)); htlc_state_name(hin->hstate));
if (htlc_is_trimmed(REMOTE, hin->msat, local_feerate, if (htlc_is_trimmed(REMOTE, hin->msat, local_feerate,
channel->our_config.dust_limit, LOCAL, 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_add_bool(response, "local_trimmed", true);
if (hin->status != NULL) if (hin->status != NULL)
json_add_string(response, "status", hin->status); json_add_string(response, "status", hin->status);
@@ -496,7 +497,8 @@ static void json_add_htlcs(struct lightningd *ld,
htlc_state_name(hout->hstate)); htlc_state_name(hout->hstate));
if (htlc_is_trimmed(LOCAL, hout->msat, local_feerate, if (htlc_is_trimmed(LOCAL, hout->msat, local_feerate,
channel->our_config.dust_limit, LOCAL, 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_add_bool(response, "local_trimmed", true);
json_object_end(response); 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 dust_limit;
struct amount_sat fee; struct amount_sat fee;
bool option_anchor_outputs = channel_has(channel, OPT_ANCHOR_OUTPUTS); 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) if (side == LOCAL)
dust_limit = channel->our_config.dust_limit; 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" */ /* Assume we tried to add "amount" */
if (!htlc_is_trimmed(side, amount, feerate, dust_limit, side, 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++; num_untrimmed_htlcs++;
for (hin = htlc_in_map_first(ld->htlcs_in, &ini); 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) if (hin->key.channel != channel)
continue; continue;
if (!htlc_is_trimmed(!side, hin->msat, feerate, dust_limit, 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++; num_untrimmed_htlcs++;
} }
for (hout = htlc_out_map_first(ld->htlcs_out, &outi); 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) if (hout->key.channel != channel)
continue; continue;
if (!htlc_is_trimmed(side, hout->msat, feerate, dust_limit, 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++; num_untrimmed_htlcs++;
} }
@@ -563,9 +566,9 @@ static struct amount_sat commit_txfee(const struct channel *channel,
* predictability between implementations. * predictability between implementations.
*/ */
fee = commit_tx_base_fee(2 * feerate, num_untrimmed_htlcs + 1, 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: /* BOLT #3:
* If `option_anchors` applies to the commitment * If `option_anchors` applies to the commitment
* transaction, also subtract two times the fixed anchor size * 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"); json_add_string(response, NULL, "option_static_remotekey");
if (channel_has(channel, OPT_ANCHOR_OUTPUTS)) if (channel_has(channel, OPT_ANCHOR_OUTPUTS))
json_add_string(response, NULL, "option_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)) if (channel_has(channel, OPT_ZEROCONF))
json_add_string(response, NULL, "option_zeroconf"); json_add_string(response, NULL, "option_zeroconf");
if (channel_has(channel, OPT_SCID_ALIAS)) 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, u32 feerate_per_kw UNNEEDED,
struct amount_sat dust_limit UNNEEDED, struct amount_sat dust_limit UNNEEDED,
enum side side 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(); } { fprintf(stderr, "htlc_is_trimmed called!\n"); abort(); }
/* Generated stub for htlc_max_possible_send */ /* Generated stub for htlc_max_possible_send */
struct amount_msat htlc_max_possible_send(const struct channel *channel UNNEEDED) 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, htlc_amount,
to_self_delay[LOCAL], to_self_delay[LOCAL],
0, 0,
keyset, option_anchor_outputs); keyset,
option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
/* BOLT #3: /* 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, htlc_scripts[i] = htlc_offered_wscript(htlc_scripts,
&htlcs[i].ripemd, &htlcs[i].ripemd,
keyset, keyset,
option_anchor_outputs || option_anchors_zero_fee_htlc_tx); option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
else { else {
/* FIXME: remove abs_locktime */ /* FIXME: remove abs_locktime */
struct abs_locktime ltime; struct abs_locktime ltime;
@@ -1835,7 +1838,8 @@ static u8 **derive_htlc_scripts(const struct htlc_stub *htlcs, enum side side)
&htlcs[i].ripemd, &htlcs[i].ripemd,
&ltime, &ltime,
keyset, keyset,
option_anchor_outputs || option_anchors_zero_fee_htlc_tx); option_anchor_outputs,
option_anchors_zero_fee_htlc_tx);
} }
} }
return htlc_scripts; return htlc_scripts;
@@ -1883,7 +1887,8 @@ static size_t resolve_our_htlc_ourcommit(struct tracked_output *out,
htlc_scripts[matches[i]], htlc_amount, htlc_scripts[matches[i]], htlc_amount,
htlcs[matches[i]].cltv_expiry, htlcs[matches[i]].cltv_expiry,
to_self_delay[LOCAL], 0, keyset, 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, if (set_htlc_timeout_fee(tx, out->remote_htlc_sig,
htlc_scripts[matches[i]])) 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, u8 *htlc_offered_wscript(const tal_t *ctx UNNEEDED,
const struct ripemd160 *ripemd UNNEEDED, const struct ripemd160 *ripemd UNNEEDED,
const struct keyset *keyset 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(); } { fprintf(stderr, "htlc_offered_wscript called!\n"); abort(); }
/* Generated stub for htlc_received_wscript */ /* Generated stub for htlc_received_wscript */
u8 *htlc_received_wscript(const tal_t *ctx UNNEEDED, u8 *htlc_received_wscript(const tal_t *ctx UNNEEDED,
const struct ripemd160 *ripemd UNNEEDED, const struct ripemd160 *ripemd UNNEEDED,
const struct abs_locktime *expiry UNNEEDED, const struct abs_locktime *expiry UNNEEDED,
const struct keyset *keyset 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(); } { fprintf(stderr, "htlc_received_wscript called!\n"); abort(); }
/* Generated stub for htlc_success_tx */ /* Generated stub for htlc_success_tx */
struct bitcoin_tx *htlc_success_tx(const tal_t *ctx UNNEEDED, 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, u16 to_self_delay UNNEEDED,
u32 feerate_per_kw UNNEEDED, u32 feerate_per_kw UNNEEDED,
const struct keyset *keyset 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(); } { fprintf(stderr, "htlc_success_tx called!\n"); abort(); }
/* Generated stub for master_badmsg */ /* Generated stub for master_badmsg */
void master_badmsg(u32 type_expected UNNEEDED, const u8 *msg) 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, u16 to_self_delay UNNEEDED,
u32 feerate_per_kw UNNEEDED, u32 feerate_per_kw UNNEEDED,
const struct keyset *keyset 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 bitcoin_tx *tx;
struct amount_sat in_amount; 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, u8 *htlc_offered_wscript(const tal_t *ctx UNNEEDED,
const struct ripemd160 *ripemd UNNEEDED, const struct ripemd160 *ripemd UNNEEDED,
const struct keyset *keyset 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(); } { fprintf(stderr, "htlc_offered_wscript called!\n"); abort(); }
/* Generated stub for htlc_received_wscript */ /* Generated stub for htlc_received_wscript */
u8 *htlc_received_wscript(const tal_t *ctx UNNEEDED, u8 *htlc_received_wscript(const tal_t *ctx UNNEEDED,
const struct ripemd160 *ripemd UNNEEDED, const struct ripemd160 *ripemd UNNEEDED,
const struct abs_locktime *expiry UNNEEDED, const struct abs_locktime *expiry UNNEEDED,
const struct keyset *keyset 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(); } { fprintf(stderr, "htlc_received_wscript called!\n"); abort(); }
/* Generated stub for htlc_success_tx */ /* Generated stub for htlc_success_tx */
struct bitcoin_tx *htlc_success_tx(const tal_t *ctx UNNEEDED, 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, u16 to_self_delay UNNEEDED,
u32 feerate_per_kw UNNEEDED, u32 feerate_per_kw UNNEEDED,
const struct keyset *keyset 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(); } { fprintf(stderr, "htlc_success_tx called!\n"); abort(); }
/* Generated stub for htlc_timeout_tx */ /* Generated stub for htlc_timeout_tx */
struct bitcoin_tx *htlc_timeout_tx(const tal_t *ctx UNNEEDED, 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, u16 to_self_delay UNNEEDED,
u32 feerate_per_kw UNNEEDED, u32 feerate_per_kw UNNEEDED,
const struct keyset *keyset 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(); } { fprintf(stderr, "htlc_timeout_tx called!\n"); abort(); }
/* Generated stub for master_badmsg */ /* Generated stub for master_badmsg */
void master_badmsg(u32 type_expected UNNEEDED, const u8 *msg) 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 *remoteconf,
const struct channel_config *localconf, const struct channel_config *localconf,
bool option_anchor_outputs, bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx,
char **err_reason) char **err_reason)
{ {
struct amount_sat capacity; struct amount_sat capacity;
@@ -72,7 +73,7 @@ bool check_config_bounds(const tal_t *ctx,
* `to_remote_anchor` above its reserve. * `to_remote_anchor` above its reserve.
*/ */
/* (We simply include in "reserve" here if they opened). */ /* (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))) { && !amount_sat_add(&reserve, reserve, AMOUNT_SAT(660))) {
*err_reason = tal_fmt(ctx, *err_reason = tal_fmt(ctx,
"cannot add anchors to reserve %s", "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, /* They have to pay for fees, too. Assuming HTLC is dust, though,
* we don't account for an HTLC output. */ * 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)) { if (!amount_sat_sub(&capacity, capacity, fee)) {
*err_reason = tal_fmt(ctx, "channel_reserve_satoshis %s" *err_reason = tal_fmt(ctx, "channel_reserve_satoshis %s"
" and %s plus fee %s too large for " " 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 *remoteconf,
const struct channel_config *localconf, const struct channel_config *localconf,
bool option_anchor_outputs, bool option_anchor_outputs,
bool option_anchors_zero_fee_htlc_tx,
char **err_reason); char **err_reason);
bool anchors_negotiated(struct feature_set *our_features, 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, state->min_effective_htlc_capacity,
&tx_state->remoteconf, &tx_state->remoteconf,
&tx_state->localconf, &tx_state->localconf,
anchors_negotiated(state->our_features, feature_negotiated(state->our_features,
state->their_features), state->their_features,
OPT_ANCHOR_OUTPUTS),
feature_negotiated(state->our_features,
state->their_features,
OPT_ANCHORS_ZERO_FEE_HTLC_TX),
&err_reason)) { &err_reason)) {
negotiation_failed(state, "%s", err_reason); negotiation_failed(state, "%s", err_reason);
return; return;
@@ -3305,8 +3309,12 @@ static void opener_start(struct state *state, u8 *msg)
state->min_effective_htlc_capacity, state->min_effective_htlc_capacity,
&tx_state->remoteconf, &tx_state->remoteconf,
&tx_state->localconf, &tx_state->localconf,
anchors_negotiated(state->our_features, feature_negotiated(state->our_features,
state->their_features), state->their_features,
OPT_ANCHOR_OUTPUTS),
feature_negotiated(state->our_features,
state->their_features,
OPT_ANCHORS_ZERO_FEE_HTLC_TX),
&err_reason)) { &err_reason)) {
negotiation_failed(state, "%s", err_reason); negotiation_failed(state, "%s", err_reason);
return; return;
@@ -3615,8 +3623,12 @@ static void rbf_local_start(struct state *state, u8 *msg)
state->min_effective_htlc_capacity, state->min_effective_htlc_capacity,
&tx_state->remoteconf, &tx_state->remoteconf,
&tx_state->localconf, &tx_state->localconf,
anchors_negotiated(state->our_features, feature_negotiated(state->our_features,
state->their_features), state->their_features,
OPT_ANCHOR_OUTPUTS),
feature_negotiated(state->our_features,
state->their_features,
OPT_ANCHORS_ZERO_FEE_HTLC_TX),
&err_reason)) { &err_reason)) {
open_abort(state, "%s", err_reason); open_abort(state, "%s", err_reason);
return; return;
@@ -3753,8 +3765,12 @@ static void rbf_remote_start(struct state *state, const u8 *rbf_msg)
state->min_effective_htlc_capacity, state->min_effective_htlc_capacity,
&tx_state->remoteconf, &tx_state->remoteconf,
&tx_state->localconf, &tx_state->localconf,
anchors_negotiated(state->our_features, feature_negotiated(state->our_features,
state->their_features), state->their_features,
OPT_ANCHOR_OUTPUTS),
feature_negotiated(state->our_features,
state->their_features,
OPT_ANCHORS_ZERO_FEE_HTLC_TX),
&err_reason)) { &err_reason)) {
negotiation_failed(state, "%s", err_reason); negotiation_failed(state, "%s", err_reason);
goto free_rbf_ctx; 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->min_effective_htlc_capacity,
&state->remoteconf, &state->remoteconf,
&state->localconf, &state->localconf,
anchors_negotiated(state->our_features, feature_negotiated(state->our_features,
state->their_features), state->their_features,
OPT_ANCHOR_OUTPUTS),
feature_negotiated(state->our_features,
state->their_features,
OPT_ANCHORS_ZERO_FEE_HTLC_TX),
&err_reason)) { &err_reason)) {
negotiation_failed(state, "%s", err_reason); negotiation_failed(state, "%s", err_reason);
return NULL; return NULL;
@@ -1085,8 +1089,12 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
state->min_effective_htlc_capacity, state->min_effective_htlc_capacity,
&state->remoteconf, &state->remoteconf,
&state->localconf, &state->localconf,
anchors_negotiated(state->our_features, feature_negotiated(state->our_features,
state->their_features), state->their_features,
OPT_ANCHOR_OUTPUTS),
feature_negotiated(state->our_features,
state->their_features,
OPT_ANCHORS_ZERO_FEE_HTLC_TX),
&err_reason)) { &err_reason)) {
negotiation_failed(state, "%s", err_reason); negotiation_failed(state, "%s", err_reason);
return NULL; 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 # reconnect with l1, which will fulfill the payment
l2.rpc.connect(l1.info['id'], 'localhost', l1.port) 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 # l2 moves on for closed l3
bitcoind.generate_block(1, wait_for_mempool=1) 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: * set to `1` and witness:
*/ */
if (utxos[i]->close_info 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; this_nsequence = utxos[i]->close_info->csv;
else else
this_nsequence = nsequence; this_nsequence = nsequence;

View File

@@ -234,7 +234,8 @@ bool htlc_is_trimmed(enum side htlc_owner UNNEEDED,
u32 feerate_per_kw UNNEEDED, u32 feerate_per_kw UNNEEDED,
struct amount_sat dust_limit UNNEEDED, struct amount_sat dust_limit UNNEEDED,
enum side side 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(); } { fprintf(stderr, "htlc_is_trimmed called!\n"); abort(); }
/* Generated stub for htlc_set_add */ /* Generated stub for htlc_set_add */
void htlc_set_add(struct lightningd *ld UNNEEDED, 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->channel_id = 42;
u.close_info->peer_id = id; u.close_info->peer_id = id;
u.close_info->commitment_point = &pk; 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 */ /* Arbitrarily set scriptpubkey len to 20 */
u.scriptPubkey = tal_arr(w, u8, 20); u.scriptPubkey = tal_arr(w, u8, 20);
memset(u.scriptPubkey, 1, 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 && CHECK(u.close_info->channel_id == 42 &&
pubkey_eq(u.close_info->commitment_point, &pk) && pubkey_eq(u.close_info->commitment_point, &pk) &&
node_id_eq(&u.close_info->peer_id, &id) && 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 */ /* Attempt to reserve the utxo */
CHECK_MSG(wallet_update_output_status(w, &u.outpoint, 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->channel_id = 42;
u.close_info->peer_id = id; u.close_info->peer_id = id;
u.close_info->commitment_point = NULL; 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 /* The blockheight has to be set for an option_anchor_output
* closed UTXO to be spendable */ * closed UTXO to be spendable */
u32 *blockheight = tal(w, u32); 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 && CHECK(u.close_info->channel_id == 42 &&
u.close_info->commitment_point == NULL && u.close_info->commitment_point == NULL &&
node_id_eq(&u.close_info->peer_id, &id) && 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); u.close_info->csv == 1);
/* Now un-reserve them */ /* Now un-reserve them */
tal_free(utxos); 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 && CHECK(u.close_info->channel_id == 42 &&
u.close_info->commitment_point == NULL && u.close_info->commitment_point == NULL &&
node_id_eq(&u.close_info->peer_id, &id) && 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); u.close_info->csv > 0);
} }
/* Now un-reserve them */ /* 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); db_bind_pubkey(stmt, 8, utxo->close_info->commitment_point);
else else
db_bind_null(stmt, 8); 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 { } else {
db_bind_null(stmt, 6); db_bind_null(stmt, 6);
db_bind_null(stmt, 7); 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, = db_col_optional(utxo->close_info, stmt,
"commitment_point", "commitment_point",
pubkey); pubkey);
utxo->close_info->option_anchor_outputs utxo->close_info->option_anchors
= db_col_int(stmt, "option_anchor_outputs"); = db_col_int(stmt, "option_anchor_outputs");
utxo->close_info->csv = db_col_int(stmt, "csv_lock"); utxo->close_info->csv = db_col_int(stmt, "csv_lock");
} else { } else {
@@ -519,9 +519,11 @@ static bool deep_enough(u32 maxheight, const struct utxo *utxo,
u32 current_blockheight) u32 current_blockheight)
{ {
if (utxo->close_info if (utxo->close_info
&& utxo->close_info->option_anchor_outputs) { && utxo->close_info->option_anchors) {
/* All option_anchor_output close_infos /* BOLT #3:
* have a csv of at least 1 */ * If `option_anchors` applies to the commitment transaction, the
* `to_remote` output is encumbered by a one block csv lock.
*/
if (!utxo->blockheight) if (!utxo->blockheight)
return false; return false;
@@ -658,7 +660,8 @@ bool wallet_add_onchaind_utxo(struct wallet *w,
else else
db_bind_null(stmt, 8); 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); db_bind_int(stmt, 10, blockheight);
/* spendheight */ /* spendheight */
@@ -896,7 +899,7 @@ done:
static struct bitcoin_signature * static struct bitcoin_signature *
wallet_htlc_sigs_load(const tal_t *ctx, struct wallet *w, u64 channelid, 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 db_stmt *stmt;
struct bitcoin_signature *htlc_sigs = tal_arr(ctx, struct bitcoin_signature, 0); 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 * transaction, `SIGHASH_SINGLE|SIGHASH_ANYONECANPAY` is
* used as described in [BOLT #5] * used as described in [BOLT #5]
*/ */
if (option_anchor_outputs) if (option_anchors)
sig.sighash_type = SIGHASH_SINGLE|SIGHASH_ANYONECANPAY; sig.sighash_type = SIGHASH_SINGLE|SIGHASH_ANYONECANPAY;
else else
sig.sighash_type = SIGHASH_ALL; sig.sighash_type = SIGHASH_ALL;
@@ -1526,8 +1529,7 @@ static struct channel *wallet_stmt2channel(struct wallet *w, struct db_stmt *stm
&last_sig, &last_sig,
wallet_htlc_sigs_load(tmpctx, w, wallet_htlc_sigs_load(tmpctx, w,
db_col_u64(stmt, "id"), db_col_u64(stmt, "id"),
channel_type_has(type, OPT_ANCHOR_OUTPUTS) channel_type_has_anchors(type)),
|| channel_type_has(type, OPT_ANCHORS_ZERO_FEE_HTLC_TX)),
&channel_info, &channel_info,
take(fee_states), take(fee_states),
remote_shutdown_scriptpubkey, remote_shutdown_scriptpubkey,