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

Inbound routing fees #18

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

joostjager
Copy link

@joostjager joostjager commented Aug 29, 2022

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 to express an inbound fee discount. Senders who are able to read this field can benefit from lower routing fees using those channels.

Alternative: pairwise fees

An alternative scheme for inbound fees are the so-called pairwise fees, where a distinct fee can be set for each combination of incoming and outgoing channel. This can also be implemented as a discount to remain backwards compatible.

For this BLIP, I chose to start simple with a plain single inbound fee. A single fee only requires trivial changes to pathfinding algorithms and there is no potential for quadratic growth of gossip data.

If pairwise fees prove to be required, an additional BLIP can be defined. It can again be formulated as another discount on the general inbound discount, to keep all options open for implementers.

Additional information

@TheBlueMatt
Copy link
Contributor

IMO this should not go in the channel_update message, but rather a new point-to-point message to tell the counterparty to decrease their outbound fee by this much. That way you don't have (as much of a) chicken and eh problem when routing, but rather can let individual peer pairs upgrade and then routing nodes will all get the discount.

@joostjager
Copy link
Author

I don't see how that achieves the same goal. I am looking to make senders aware of the discount so that they can choose routes that are better for them. How will a sender become aware of that new p2p message if it is only exchanged between two remote nodes?

@TheBlueMatt
Copy link
Contributor

TheBlueMatt commented Aug 29, 2022

A channel participant can inform their counterparty that they wish to take a negative inbound fee for the channel, then their counterparty can subtract the given inbound fee from their announced outbound fees, which all existing nodes will honor. That way no one except the two channel participants needs to update any software at all. As-is, I think its a bit of a stretch to suggest this has no broad-upgrade implication.

blip-0018.md Outdated

## Universality

This feature is defined as a BLIP because it's optional.
Copy link
Contributor

Choose a reason for hiding this comment

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

This is not sufficient - bLIP 1 says that it "should discuss why the given feature is not intended to be universal" and "why it's still a good idea as a non-universal protocol". Just being option isn't sufficient for "not universal" - any change to the BOLTs is also, generally, optional as a backwards compatibility consideration.

Rather, the universality section needs to define why the change is contemplated as something that only some small fraction of nodes will ever adopt, and why its still a good idea given that only a small fraction of nodes adopt it. I think it will probably be pretty hard to write such a section for this change as-is, given it is something that only really makes sense with broad adoption. Rather, changing the spec to define something that only changes direct peer communication would likely make it more "bLIP-worthy".

@joostjager
Copy link
Author

joostjager commented Aug 29, 2022

Interesting idea. I suppose it's up to your counterparty to actually lower their outbound fee and not something that can be enforced. Which simplifies the implementation.

What's left is just the ability to tell your peer to send you fewer sats.

It may be a problem for final nodes though that also route. If they are accepting a payment as the final destination, they'll also receive less and this can't be offset by an outgoing fee. The counterparty doesn't know which position in the route they are.

@TheBlueMatt
Copy link
Contributor

TheBlueMatt commented Aug 29, 2022

I suppose it's up to your counterparty to actually lower their outbound fee and not something that can be enforced.

Sure, they could also increase their fee corresponding to your negative fees in the current implementation too :).

It may be a problem for final nodes though that also route. If they are accepting a payment as the final destination, they'll also receive less and this can't be offset by an outgoing fee.

Hmm, yea, neither the existing nor the new proposal really properly lets you assign positive fees on inbound edges (by offsetting negative fees with outbound fee increases) for this reason, I suppose. I guess the "easy" way to fix that is to use something like phantom nodes and assign the fee offset to the fake hop.

@joostjager
Copy link
Author

Well in the existing proposal, the sender is aware of the final hop. This BLIP says that no inbound fee needs to be paid to the final node, and the sender can take that into account when building the route.

Yes, a fake node can be used to let the payer pay for the discount they got :)

With the new p2p proposal, it may not be necessary anymore to do negative fees. That was just for backwards compatibility. I think it can be reformulated to positive fees. Basically forcing your peer to share part of their outbound fee with you.

For the final node, this would be a little better I guess because at least your getting the invoice amount.

@TheBlueMatt
Copy link
Contributor

With the new p2p proposal, it may not be necessary anymore to do negative fees. That was just for backwards compatibility. I think it can be reformulated to positive fees. Basically forcing your peer to share part of their outbound fee with you.

That's true, but it complicates the backwards-compatibility story - why would I ever deploy a change that results in my counterparty increasing the fee on a channel of mine, that just results in less routing revenue for me. Sure, a node may prefer channels with peers that support the new option, but I'm not sure if anyone will prefer that so strongly that they'll reject other new inbound channels.

@joostjager
Copy link
Author

I think that not having the ability to charge inbound fees is at this moment already a strong reason for node operators to reject / close certain inbound channels.

I can see this option becoming a requirement for those nodes. The win is that they can keep channels open that they would otherwise close.

@TheBlueMatt
Copy link
Contributor

If you assume very broad deployment of that feature, then yes, I think I'd agree, but in that case I don't think the feature is really a decent candidate for being a bLIP, but rather needs to be a BOLT change :p.

blip-0018.md Outdated
for the incoming and outgoing channel that is used. This should amount to a
lower value than just the outbound fee.

`outbound_fee(amt_to_fwd) + inbound_fee(amt_to_fwd + outbound_fee(amt_to_fwd))`
Copy link
Contributor

Choose a reason for hiding this comment

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

Alternatively, the inbound fees described above could be positive numbers, shifting explicitly shifting the subtraction here.

Copy link
Author

Choose a reason for hiding this comment

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

Yes, considered that. But perhaps there is a future where all senders have upgraded and we shift to actual positive inbound fees, which would then be represented as negative discounts. Not optimally consistent. Of course this is all just cosmetics.

@joostjager
Copy link
Author

Need to think about what to do with the insufficient fee failure message. Maybe extend with the channel update message for the incoming channel?

@TheBlueMatt
Copy link
Contributor

I don't think anything needs to change? The first node compares the fee paid according to the onion to what they announced (including the discount). The discount only applies at the update_add_htlc layer, so no changes needed.

@joostjager
Copy link
Author

Ah, this was a comment about the channel_update extension proposal. In the p2p solution, nothing like that is needed indeed.

One thing that worries me about the p2p proposal is that it probably requires changes to the channel state machine so that it will be clear from what point onwards exactly the new fee applies.

@TheBlueMatt
Copy link
Contributor

I'm not sure how this differs - either way you have a new argument to your logic that checks an HTLC pays the appropriate fees. There is a slight difference on your peer's side in that they have to subtract the fee amount rather than seeing it in the onion, but that's really rather trivial as well.

I'm kinda unsure why we're arguing so much about this one - one proposal requires network-wide upgrade in order for your fee to be considered (the ultimate goal of anyone providing a fee discount), one does not. Given there was some debate about this being not-widely-deployed that seems like a rather massive advantage.

@joostjager
Copy link
Author

I did a PoC for the p2p inbound fee: lightningnetwork/lnd#6878

Overall a fairly straight-forward change. A real functional difference only seems to exist for nodes that are both routing nodes and a payment destination.

A fake hop was suggested in #18 (comment), but this does add complexity to the setup and it won't be possible to cancel out the discount exactly.

@joostjager
Copy link
Author

One downside of the p2p approach is that if the incoming node already charges zero fees, they can't lower their fee any further. So giving them a discount isn't going to make a difference. If there are multiple zero or low fee peers, it won't be possible to have distinct inbound fee schedules for these peers.

@TheBlueMatt
Copy link
Contributor

Right, but in those same cases routing algorithms would need to be modified to support negative fees, which AFAIK no existing node supports. I think negative fees are somewhat of an orthogonal discussion.

@joostjager
Copy link
Author

Yes, that's true. Over time, when senders are mostly upgraded, you could switch to positive inbound fees to get around the pathfinding limitation.

Although for p2p this may be uncomfortable for peers, because they need to monitor the inbound fee closely and adjust their fees accordingly to make sure they charge as much as they need to pay p2p to the next node and keep it net zero.

@TheBlueMatt
Copy link
Contributor

Although for p2p this may be uncomfortable for peers, because they need to monitor the inbound fee closely and adjust their fees accordingly to make sure they charge as much as they need to pay p2p to the next node and keep it net zero.

I'm not sure why this is different from today, really? Peers have to watch for channel updates from their peers and track updated routing fees, now they just also have to broadcast their own updates in response to a new message that's similar in nature.

blip-0018.md Outdated
incoming_amt = divideRoundAwayFromZero((amt_to_receive+int64(inbound_fee.base_msat))*1e6, (1e6 - int64(inbound_fee.proportional_millionths)))
} else {
incoming_amt = divide((amt_to_receive+int64(inbound_fee.base_msat))*1e6, (1e6 - int64(inbound_fee.proportional_millionths)))
}
Copy link
Author

@joostjager joostjager Sep 6, 2022

Choose a reason for hiding this comment

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

Figured this out by trial-and-error and running a large numbers of values through the formula to see if it checks out. Would be nice if someone who really understands equations with integer math could validate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants