From ed56b22094878193426891ef332d37ffde42955c Mon Sep 17 00:00:00 2001 From: Michael Schmoock Date: Sun, 8 Mar 2020 14:39:32 +0100 Subject: [PATCH] fix: calc commit_txfee_spend/recv for spendable or receivable --- lightningd/peer_control.c | 68 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 4 deletions(-) diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 1775f9ac8..4f14e0704 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -509,9 +509,10 @@ static void json_add_sat_only(struct json_stream *result, type_to_string(tmpctx, struct amount_msat, &msat)); } +/* Fee a commitment transaction would currently cost when spending */ /* This is quite a lot of work to figure out what it would cost us! */ -static struct amount_sat commit_txfee(const struct channel *channel, - struct amount_msat spendable) +static struct amount_sat commit_txfee_spend(const struct channel *channel, + struct amount_msat spendable) { /* FIXME: make per-channel htlc maps! */ const struct htlc_in *hin; @@ -567,6 +568,65 @@ static struct amount_sat commit_txfee(const struct channel *channel, return commit_tx_base_fee(local_feerate * 2, num_untrimmed_htlcs + 1); } +/* Fee a commitment transaction would currently cost when receiving */ +static struct amount_sat commit_txfee_recv(const struct channel *channel, + struct amount_msat receivable) +{ + /* FIXME: make per-channel htlc maps! */ + const struct htlc_in *hin; + struct htlc_in_map_iter ini; + const struct htlc_out *hout; + struct htlc_out_map_iter outi; + struct lightningd *ld = channel->peer->ld; + u32 feerate = get_feerate(channel->channel_info.fee_states, + channel->funder, REMOTE); + size_t num_untrimmed_htlcs = 0; + + /* Assume we tried to receive "receivable" */ + if (!htlc_is_trimmed(REMOTE, receivable, feerate, + channel->channel_info.their_config.dust_limit, + REMOTE)) + num_untrimmed_htlcs++; + + for (hin = htlc_in_map_first(&ld->htlcs_in, &ini); + hin; + hin = htlc_in_map_next(&ld->htlcs_in, &ini)) { + if (hin->key.channel != channel) + continue; + if (!htlc_is_trimmed(LOCAL, hin->msat, feerate, + channel->channel_info.their_config.dust_limit, + REMOTE)) + num_untrimmed_htlcs++; + } + for (hout = htlc_out_map_first(&ld->htlcs_out, &outi); + hout; + hout = htlc_out_map_next(&ld->htlcs_out, &outi)) { + if (hout->key.channel != channel) + continue; + if (!htlc_is_trimmed(REMOTE, hout->msat, feerate, + channel->channel_info.their_config.dust_limit, + REMOTE)) + num_untrimmed_htlcs++; + } + + /* + * BOLT-95c74fef2fe590cb8adbd7b848743a229ffe825a #2: + * Adding an HTLC: update_add_htlc + * + * A sending node: + * - if it is responsible for paying the Bitcoin fee: + * - SHOULD NOT offer `amount_msat` if, after adding that HTLC to + * its commitment transaction, its remaining balance doesn't allow + * it to pay the fee for a future additional non-dust HTLC at + * `N*feerate_per_kw` while maintaining its channel reserve + * ("fee spike buffer"), where `N` is a parameter chosen by the + * implementation (`N = 2` is recommended to ensure + * predictability). + */ + return commit_tx_base_fee(2 * feerate, num_untrimmed_htlcs + 1); +} + + static void subtract_offered_htlcs(const struct channel *channel, struct amount_msat *amount) { @@ -733,7 +793,7 @@ static void json_add_channel(struct lightningd *ld, /* If we're funder, subtract txfees we'll need to spend this */ if (channel->funder == LOCAL) { if (!amount_msat_sub_sat(&spendable, spendable, - commit_txfee(channel, spendable))) + commit_txfee_spend(channel, spendable))) spendable = AMOUNT_MSAT(0); } @@ -764,7 +824,7 @@ static void json_add_channel(struct lightningd *ld, /* If they're funder, subtract txfees they'll need to spend this */ if (channel->funder == REMOTE) { if (!amount_msat_sub_sat(&receivable, receivable, - commit_txfee(channel, receivable))) + commit_txfee_recv(channel, receivable))) receivable = AMOUNT_MSAT(0); }