-
Notifications
You must be signed in to change notification settings - Fork 47
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
Inbound routing fees #18
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
``` | ||
bLIP: 14 | ||
Title: Inbound routing fees | ||
Status: Draft | ||
Author: Joost Jager <[email protected]> | ||
Created: 2022-08-29 | ||
License: CC0 | ||
``` | ||
|
||
## Abstract | ||
|
||
The Lightning BOLTs define a routing fee that is based on the policy of the | ||
_outgoing_ channel. This makes it impossible for routing node operators to | ||
differentiate in fees between incoming channels. | ||
|
||
Incoming traffic from some peers may be more desired than from others, for | ||
example because it balances out traffic in the opposite direction. | ||
|
||
This bLIP defines an optional `channel_update` message field `inbound_fee` to | ||
express an inbound fee. | ||
|
||
## Copyright | ||
|
||
This bLIP is licensed under the CC0 license. | ||
|
||
## Specification | ||
|
||
Routing node: | ||
|
||
* MAY include a `channel_update` optional TLV record `inbound_fee` keyed by type | ||
`55555` with the following value: | ||
|
||
* [i32:base_msat] | ||
* [i32:proportional_millionths] | ||
|
||
* MAY choose to advertize a negative inbound fee to keep servicing senders who | ||
don't understand inbound fees. | ||
|
||
The given discount can be balanced with an increase of the outgoing fees to | ||
effectively have a positive inbound fee. | ||
|
||
* The inbound fee is calculated over the amount to forward plus the outbound | ||
fee. This amount is called the net amount received (`net_received_amt`). | ||
|
||
`net_received_amt = amt_to_fwd + outbound_fee(amt_to_fwd)` | ||
|
||
`inbound_fee(net_received_amt) = inbound_fee.base_msat + inbound_fee.proportional_millionths * net_received_amt / 1e6` | ||
|
||
Example: | ||
|
||
`inbound fee = 1 + 10%, outbound fee = 7 + 3%, outgoing htlc amount = 100` | ||
|
||
`--- 122 ---> (in fee: 12) (net_received_amt: 110) (out fee: 10) --- 100 --->` | ||
|
||
* MUST accept a routing fee equal to or greater than the sum of inbound and | ||
outbound fee. No attempt should be made to calculate the total fee in one go, | ||
because rounding may cause the end result to be higher. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the current lnd implementation, the sum of outbound and inbound must not be negative. Should the blip be updated accordingly? I think that negative fees should also be possible in the long term, but then we would probably need an additional boolean to signal a possible negative fee to the network. Otherwise sender nodes will not be able to see which routing might reject a payment with negative fees. |
||
|
||
* The inbound fee does not apply to final hops. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this shows what's wrong with this proposal : If I open a channel to X, I should be able to pay X without paying fees, it would be unfair for X to ask me to pay an extra fee for receiving my payment. Well, it's exactly the same in case X is not the final recipient but only a relay. If X really thinks that traffic from channel a is better than traffic from channel b, then why should this preference no longer hold when X is the recipient? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because the recipient isn't providing a forwarding service. It plays a different role. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why does it matter? Traffic is fungible. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd say it is different traffic, because there is no outgoing component. There is something to say for always charging, but I think it is not the best choice. I documented some thoughts about it here |
||
|
||
* For `fee_insufficient` failures, the routing node SHOULD, in addition to the | ||
outgoing channel policy, also return the incoming channel policy as a TLV | ||
extension. But only if the sender signaled support for extended failure | ||
messages. | ||
|
||
TBD: allocate type for this and describe. | ||
|
||
* MUST NOT set inbound fees on private channels. Inbound fees can't be | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this true? Seem like it could be encoded in the invoice with a new feature bit, with similar backwards compatibility as forwarding payments (start with a discount, and senders that don't understand it will overpay). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should have been "can't currently be communicated". We could add a new tag for the inbound fees, but would need to be careful not to duplicate too much information and increase the size of a qr code unnecessarily. Perhaps it's possible to do a TLV extension of the I've also looked into folding the inbound and outbound fee into a single fee, but that doesn't seem to be possible. If for example the final destination requires an inbound fee, there is no way to express that through the outbound fee of the second-last node. It will still always only send the payment amount to the final hop and not more. |
||
communicated through bolt11 invoices yet and senders will not be aware of | ||
them. | ||
|
||
Sender node: | ||
|
||
* MUST pay each routing node at least the sum of its advertised inbound and | ||
outbound fee for the incoming and outgoing channel that is used (formula above). | ||
|
||
* SHOULD signal to each node along the route that they can interpret [extended failure messages](https://github.com/lightning/bolts/pull/1021). | ||
|
||
* SHOULD apply all channels updates that accompany a `fee_insufficent` failure. | ||
The update for the incoming channel may be present in the TLV extension. | ||
|
||
## Universality | ||
|
||
This feature is defined as a BLIP because it's experimental. | ||
|
||
## Backwards Compatibility | ||
|
||
By defining the inbound fee as a negative number, senders who don't understand | ||
the new field will still be able to make payments. Routing nodes will accept | ||
overpayment on fees. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current implementation in lnd also applies to optional positive inbound fees. Should the wording be updated?