Browse Source

channeld: fix fee calculation.

Funder can't spend the fee it needs to pay for the commitment transaction:
we were not converting to millisatoshis, however!

This breaks our routeboost test, which no longer has sufficient funds
to make payment.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
plugin-7
Rusty Russell 6 years ago
committed by Christian Decker
parent
commit
a8e0e1709a
  1. 2
      CHANGELOG.md
  2. 14
      channeld/full_channel.c
  3. 6
      tests/test_invoices.py
  4. 2
      tests/test_pay.py

2
CHANGELOG.md

@ -37,8 +37,10 @@ changes.
- JSON API: uppercase invoices now parsed correctly (broken in 0.6.2). - JSON API: uppercase invoices now parsed correctly (broken in 0.6.2).
- JSON API: commands are once again read even if one hasn't responded yet (broken in 0.6.2). - JSON API: commands are once again read even if one hasn't responded yet (broken in 0.6.2).
- Protocol: allow lnd to send `update_fee` before `funding_locked`. - Protocol: allow lnd to send `update_fee` before `funding_locked`.
- Protocol: fix limit on how much funder can send (fee was 1000x too small)
- pylightning: handle multiple simultanous RPC replies reliably. - pylightning: handle multiple simultanous RPC replies reliably.
### Security ### Security

14
channeld/full_channel.c

@ -414,7 +414,7 @@ static enum channel_add_err add_htlc(struct channel *channel,
- commit_tx_num_untrimmed(removing, feerate, dust, - commit_tx_num_untrimmed(removing, feerate, dust,
recipient); recipient);
fee_msat = commit_tx_base_fee(feerate, untrimmed); fee_msat = commit_tx_base_fee(feerate, untrimmed) * 1000;
} else } else
fee_msat = 0; fee_msat = 0;
@ -684,7 +684,7 @@ static int change_htlcs(struct channel *channel,
u32 approx_max_feerate(const struct channel *channel) u32 approx_max_feerate(const struct channel *channel)
{ {
size_t num; size_t num;
u64 weight; u64 weight, avail_msat;
const struct htlc **committed, **adding, **removing; const struct htlc **committed, **adding, **removing;
gather_htlcs(tmpctx, channel, !channel->funder, gather_htlcs(tmpctx, channel, !channel->funder,
@ -695,8 +695,12 @@ u32 approx_max_feerate(const struct channel *channel)
weight = 724 + 172 * num; weight = 724 + 172 * num;
return channel->view[!channel->funder].owed_msat[channel->funder] /* We should never go below reserve. */
/ weight * 1000; avail_msat = channel->view[!channel->funder].owed_msat[channel->funder]
- channel_reserve_msat(channel, channel->funder);
/* We have to pay fee from onchain funds, so it's in satoshi. */
return avail_msat / 1000 / weight * 1000;
} }
bool can_funder_afford_feerate(const struct channel *channel, u32 feerate_per_kw) bool can_funder_afford_feerate(const struct channel *channel, u32 feerate_per_kw)
@ -714,7 +718,7 @@ bool can_funder_afford_feerate(const struct channel *channel, u32 feerate_per_kw
- commit_tx_num_untrimmed(removing, feerate_per_kw, dust, - commit_tx_num_untrimmed(removing, feerate_per_kw, dust,
!channel->funder); !channel->funder);
fee_msat = commit_tx_base_fee(feerate_per_kw, untrimmed); fee_msat = commit_tx_base_fee(feerate_per_kw, untrimmed) * 1000;
/* BOLT #2: /* BOLT #2:
* *

6
tests/test_invoices.py

@ -120,7 +120,7 @@ def test_invoice_preimage(node_factory):
def test_invoice_routeboost(node_factory, bitcoind): def test_invoice_routeboost(node_factory, bitcoind):
"""Test routeboost 'r' hint in bolt11 invoice. """Test routeboost 'r' hint in bolt11 invoice.
""" """
l1, l2 = node_factory.line_graph(2, fundamount=10**4) l1, l2 = node_factory.line_graph(2, fundamount=2 * (10**4))
# Won't get reference to route until channel is public. # Won't get reference to route until channel is public.
inv = l2.rpc.invoice(msatoshi=123456, label="inv0", description="?") inv = l2.rpc.invoice(msatoshi=123456, label="inv0", description="?")
@ -147,8 +147,8 @@ def test_invoice_routeboost(node_factory, bitcoind):
l1.rpc.pay(inv['bolt11']) l1.rpc.pay(inv['bolt11'])
wait_channel_quiescent(l1, l2) wait_channel_quiescent(l1, l2)
# Due to reserve, l1 doesn't have capacity to pay this. # Due to reserve & fees, l1 doesn't have capacity to pay this.
inv = l2.rpc.invoice(msatoshi=10**7 - 123456, label="inv2", description="?") inv = l2.rpc.invoice(msatoshi=2 * (10**7) - 123456, label="inv2", description="?")
# Check warning # Check warning
assert 'warning_capacity' in inv assert 'warning_capacity' in inv
assert 'warning_offline' not in inv assert 'warning_offline' not in inv

2
tests/test_pay.py

@ -446,7 +446,7 @@ def test_sendpay_cant_afford(node_factory):
pay(l1, l2, 10**9 + 1) pay(l1, l2, 10**9 + 1)
# This is the fee, which needs to be taken into account for l1. # This is the fee, which needs to be taken into account for l1.
available = 10**9 - 13440 available = 10**9 - 13440000
# Reserve is 1%. # Reserve is 1%.
reserve = 10**7 reserve = 10**7

Loading…
Cancel
Save