Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a bLIP for backwards-compatible inbound fees #22

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 18 additions & 3 deletions blip-0019.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,28 @@ A node receiving `inbound_fees_update`:
below zero MUST be set to zero.
* SHOULD ensure that it's next `channel_update` goes out in a timely manner,
subject to relevant rate-limits.
TheBlueMatt marked this conversation as resolved.
Show resolved Hide resolved
* MUST increase the amount forwarded in an HTLC by the advertised inbound fees.
* MUST increase the amount forwarded in an HTLC by the advertised inbound fees,
* however SHOULD delay increasing the amount forwarded by an updated inbound
fee until it has a chance to broadcast a new `channel_update` after
rate-limits.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can the node know what the rate limits are? They may be applied anywhere on the network. Or just a grace period?

Then if there are still senders who haven't received the update after the grace period, the node will start returning fee_insufficient and still see its reputation damaged because of its peer inbound fee update? Not sure if the incentives are properly aligned here.

Does the delaying add complexity in the implementation because you need to keep track of history - potentially across restarts?

The situation that I described in the comment would be useful to add here too so that implementers understand why this is important. In the BOLTS I find that there isn't always enough rationale recorded, and it gets forgotten.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can the node know what the rate limits are? They may be applied anywhere on the network. Or just a grace period?

That is up to individual nodes. Its deliberately phrased in terms of channel_update to indicate to nodes that they should use their existing rate-limiting logic they already have in place.

Then if there are still senders who haven't received the update after the grace period, the node will start returning fee_insufficient and still see its reputation damaged because of its peer inbound fee update? Not sure if the incentives are properly aligned here.

Hmm? No, this is not the case, the downstream node now is the one that gets to send the failure message (as its the one that is spamming updates) the upstream node forwarded the HTLC with stale parameters so that it wasnt blamed.

Does the delaying add complexity in the implementation because you need to keep track of history - potentially across restarts?

No more than existing delays in channel_update, basically. I mostly reused the tracking logic from there.

The situation that I described in the comment would be useful to add here too so that implementers understand why this is important. In the BOLTS I find that there isn't always enough rationale recorded, and it gets forgotten.

Good point, added more details.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is up to individual nodes. Its deliberately phrased in terms of channel_update to indicate to nodes that they should use their existing rate-limiting logic they already have in place.

What I mean is that a node's existing rate-limiting logic may not match what other nodes on the network do. The node broadcasts its channel_update, but then it is held back somewhere on the network between this node and a potential sender of a payment. How do you implement this concretely?

Hmm? No, this is not the case, the downstream node now is the one that gets to send the failure message (as its the one that is spamming updates) the upstream node forwarded the HTLC with stale parameters so that it wasnt blamed.

Let's take the example A->B->C->D again. D set an inbound fee, C broadcasted a new channel_update.

Then at some point, C receives an htlc to forward with an insufficient fee. There are two reasons why this could be:

  1. Channel update hasn't reached the sender yet
  2. Node B is not forwarding enough.

Now what is C going to do? Return fee_insufficient and potentially damage its reputation because D wanted to change its inbound fee? Or forward an insufficient amount to D and punish D while B is at fault really.

If no node ever wants to return fee_insufficient, they can just keep forwarding an amount that is too small until the final destination is reached. Seems that things get a bit strange then?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I mean is that a node's existing rate-limiting logic may not match what other nodes on the network do. The node broadcasts its channel_update, but then it is held back somewhere on the network between this node and a potential sender of a payment. How do you implement this concretely?

This is no different from any other fee on the network today. Yes, there's active discussion in setting a more common rate-limit across the network, but in general senders have to be tolerant of this and recipients should expect it sometimes.

Now what is C going to do? Return fee_insufficient and potentially damage its reputation because D wanted to change its inbound fee? Or forward an insufficient amount to D and punish D while B is at fault really.

C can tell the difference, though! If B didn't forward enough to C, C will note that it didn't get enough fee compared to the forwarding instructions in the onion, and will then fail back with fee_insufficient.


A node sending `inbound_fees_update`:
* SHOULD NOT send such a message more often than it anticipates
`channel_update` messages may be accepted by the gossip network.
* MUST verify that inbound fees corresponding with the provided settings are
paid on all HTLCs, noting that the inbound fees are calculated against the
inbound HTLC amount *before* the inbound fees are subtracted.
inbound HTLC amount *before* the inbound fees are subtracted. This includes
received payments as well as forwarded ones.
* SHOULD delay enforcing updated inbound fees for some time, congruous with
the delay applied when enforcing new fees after sending a `channel_update`.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The observed delay is also influenced by the peer that is charging the inbound fee for this node (grace period). If those periods don't line up, this node is going to return fee_insufficient and damage its reputation?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, luckily there's a super trivial solution - wait until you also see the channel_update. I mentioned that now.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it is that trivial at all. You can wait until you see the channel_update, but that doesn't tell you for how long your peer will underpay you to account for propagation of that update to the sender.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it is trivial - the forwarder should wait to enforce it until it has a chance to broadcast a new channel_update, at which point it MUST enforce the update. The recipient/inbound-fee-setter should delay enforcement until it sees the channel_update + 10 minutes (which is congruous with what it does for channel_updates normally). That shouldn't have any disagreement. If you prefer we could also apply the 10 minute timer on the forwarder's side, but its not a huge deal to send back the updated channel_update when failing.


## Rationale

Because a node cannot set the fee fields in its `channel_update` below zero,
only a node's immediate peer may utilize negative inbound fees in excess of
its outbound fees. This is useful for private channels.
its outbound fees. This may be useful for private channels where a peer can
provide a fee discount to its counterparty even though it is not available to
the global network.

Because senders calculate fees based on the amount as they think it will be
forwarded, inbound fees must be checked by adding required fees back up from
Expand All @@ -65,6 +73,13 @@ sending node (likely) expected the processing node to receive. From there, the
processing node can calculate the inbound fee it expected and check that it was
included in the forwarded HTLC.

Note that inbound fees are charged both on forwarded payments and inbound
payments to prevent a forwarding node from probing to determine if the next hop
is the final destination by checking if the recipient enforces inbound fees.
This also ensures that nodes charging inbound fees for the purpose of
encouraging HTLCs be routed over a given path applies to all HTLCs, not only a
subset.

## Motivation

Many lightning node operators have expressed a desire for "inbound routing fees," i.e. fees which a sender must pay when forwarding *inbound* through a channel, rather than outbound. There is some debate as to whether such fees make sense in the general case - ultimately it's not the fee-charging node's liquidity which is being used here, so why can they charge a fee for it?
Expand Down