2

I am testing my own routing implementation and for some weird reason a handful of channels reject my payment stating InsufficientFee.

The scenario is A -c1-> B -c2-> C whereby Node A is sending a payment to C via B where the channels used are denoted as c1 and c2.

For c1 the node fee policies are

    "node1_policy": {
        "time_lock_delta": 40,
        "min_htlc": "1",
        "fee_base_msat": "1000",
        "fee_rate_milli_msat": "1",
        "max_htlc_msat": "16777215000",
    },
    "node2_policy": {
        "time_lock_delta": 144,
        "min_htlc": "1000",
        "fee_base_msat": "1000",
        "fee_rate_milli_msat": "100",
        "max_htlc_msat": "16777215000",
    },

For c2 the node fee policies are

    "node1_policy": null,
    "node2_policy": {
        "time_lock_delta": 144,
        "min_htlc": "1000",
        "fee_base_msat": "10000",
        "fee_rate_milli_msat": "100",
        "max_htlc_msat": "10000000000",

    }

For an amount of 4999000 mSat queryroutes uses this route and calculates the fees as

{'amt_to_forward': '4999',
                       'amt_to_forward_msat': '4999000',
                       'chan_capacity': '16777215',
                       'chan_id': 'c1',
                       'fee': '10',
                       'fee_msat': '10499',},
                      {'amt_to_forward': '4999',
                       'amt_to_forward_msat': '4999000',
                       'chan_capacity': '10000000',
                       'chan_id': 'c2',
                       'fee': '0',
                       'fee_msat': '0',}
             'total_amt': '5009',
             'total_amt_msat': '5009499',
             'total_fees': '10',
             'total_fees_msat': '10499',}

Could someone please explain in step-by-step detail how the lnd client gets to this value?

1

To answer your question two things have to be known:

  1. Routing fees are always charged from the recipient to the sender as the fee rate of later packages impacts earlier routing decisions.
  2. Nodes get paid a routing fee to forward a package on an outgoing channel.

The first remark is not of importance for your case as the path only includes 1 routing node. The second remark means that only the fee police for channel c2 are relevant. Node A does not charge itself a routing fee on channel c1 to forward to B and node B would only charge a fee on channel c1 if a paymant was to be forwarded to node A

So let us look at the payment amount and the policy of channel c2 the policy says:

 "fee_base_msat": "10000",
 "fee_rate_milli_msat": "100",

where the payment_amount is 4999 that means that you have to send an onion to B that has the following amount of msat

payment_amount * 1000 + fee_base_msat + payment_amount * fee_rate_milli_msat / 1'000

pluging in your numbers this means:

4999000 + 10000 + 4999 * 100 / 1000 = 5009000 + int(499.9) = 5009000 + 499 = 5009499

That is exactly the amount your node sends on its way to complete the onion. Also note that if your node would have been forwarding that payment from anouther node E the other node would have to use that result as the payment_amount with the above formula and your channel police from c1 to forward the payment. That is what I meant in the first remark that the amounts are calculated from the receiver to the sender.

  • Thank you for answering, However it seems that the lnd client rounds payments, if I enter 4999999 its rounded to 4999000 surely it should not do this? Edit: queryroutes takes Satoshis, not mSat, so the rounding will always occur regardless. – Oonah Nov 13 '19 at 14:17
  • One issue I found now, that i cannot seem to explain is, in one case n1_policy is 'fee_base_msat': '489', 'fee_rate_milli_msat': '1000', whilst n2_policy is 'fee_base_msat': '1000', 'fee_rate_milli_msat': '1',. In this case n1 received the payment, why would lnd choose n1 policy instead of n2 ? – Oonah Nov 13 '19 at 16:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.