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

Avoid stuck channels after fee increase with additional reserve #740

Merged
merged 9 commits into from
Apr 27, 2020
27 changes: 24 additions & 3 deletions 02-peer-protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -787,9 +787,22 @@ is destined, is described in [BOLT #4](04-onion-routing.md).
#### Requirements

A sending node:
- MUST NOT offer `amount_msat` it cannot pay for in the
remote commitment transaction at the current `feerate_per_kw` (see "Updating
Fees") while maintaining its channel reserve.
- if it is _responsible_ for paying the Bitcoin fee:
- MUST NOT offer `amount_msat` if, after adding that HTLC to its commitment
transaction, it cannot pay the fee for either the local or remote commitment
transaction at the current `feerate_per_kw` while maintaining its channel
reserve (see [Updating Fees](#updating-fees-update_fee)).
- SHOULD NOT offer `amount_msat` if, after adding that HTLC to its commitment
Copy link
Contributor

Choose a reason for hiding this comment

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

Now this sounds like the sender must be able to send another HTLC before this one settles. I think we should say just "the remaining balance after it has settled doesn't..."

Copy link
Collaborator Author

@t-bast t-bast Mar 27, 2020

Choose a reason for hiding this comment

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

On the contrary, I think that "after it has settled" would be incorrect for two reasons:

  • this paragraph shouldn't prevent you from sending multiple HTLCs (not settled) as long as your fee buffer allows it
  • when you send an outgoing htlc, you should be able to receive an incoming htlc: this way even if your outgoing htlc is stuck in your commit tx, you can receive an incoming to increase your balance and prevent your channel from being stuck. The case where the first outgoing htlc is still in the commit tx costs more fees than the case where it has settled, so that should be handled.

Does this make sense or am I missing something?
Note that while the htlc is pending, its value is still subtracted from your balance, so it is taken into account.

Copy link
Contributor

@halseth halseth Mar 27, 2020

Choose a reason for hiding this comment

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

I think it comes down to how strict you want to be. The channel being stuck because you have a pending HTLC on it is arguably not stuck, since it will eventually settle or cancel.

even if your outgoing htlc is stuck in your commit tx, you can receive an incoming

Not sure how important this is?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Now this sounds like the sender must be able to send another HTLC before this one settles.

It's more that the current wording allows the sender to send another HTLC before this one settles (if he has the balance to do so). IIUC your proposal disallows that, and I don't see why we'd need to be that restrictive.

Not sure how important this is?

If you disallow that, that means you potentially need to wait for a cltv-timeout before you can unblock your channel. True, it will eventually settle, but there's no reason to wait for that and be penalized by a stuck HTLC. If you can accept an incoming HTLC even though the outgoing is still pending, that allows you to increase your balance and then send other outgoing HTLCs, which increases your relay throughput.

I think the current wording is less strict than what you propose: you just deal with the present situation instead of predicting the situation after the htlc is settled. Is this correct or am I misunderstanding your point?

Copy link
Contributor

Choose a reason for hiding this comment

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

It's more that the current wording allows the sender to send another HTLC before this one settles (if he has the balance to do so).

No, if the sender has some balance left, he must reserve this for fees to receive another HTLC. What I suggested allows using more of this balance, since only after it settles we require an HTLC to be received.

If you can accept an incoming HTLC even though the outgoing is still pending, that allows you to increase your balance and then send other outgoing HTLCs, which increases your relay throughput.

This is true, the current wording makes sure the channel is stuck "less" 😛 What I meant with the current working being more strict is that it also disallows the "stuck-while-HTLC-pending" case.

To summarize the way I interpret this: the current wording requires the initiator to always keep enough balance to receive another HTLC. My suggestion was to loosen this to require the initiator to keep enough balance to receive another HTLC when there are no HTLCs pending.

Copy link
Collaborator Author

@t-bast t-bast Mar 27, 2020

Choose a reason for hiding this comment

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

To summarize the way I interpret this: the current wording requires the initiator to always keep enough balance to receive another HTLC. My suggestion was to loosen this to require the initiator to keep enough balance to receive another HTLC when there are no HTLCs pending.

Thanks, this is a lot clearer with that explanation. It is an alternative that makes sense, but it has a small additional trade-off and I prefer the current proposal 😄.

This issue happens when the balance on your side is low (very close to the reserve). When that happens, I think you should prioritize incoming HTLCs (that will increase your balance), not outgoing HTLCs (that keep getting you closer to a stuck/depleted channel).

I see two reasons for that. The first one is that the additional outgoing HTLC that you could send is tiny (it's on the order of an htlc fee), so it isn't a game-changer to allow it to go through. The second reason is that you're reducing the window of time where you allow incoming HTLCs to restore balance in your channel. While you have that last outgoing HTLC in your commitment, you are rejecting incoming HTLCs (which could have helped your channel balance). When that last outgoing HTLC settles, if you re-add another outgoing one you missed your opportunity window to receive an incoming HTLC and you need to wait for another outgoing HTLC to settle. And I think that incoming HTLCs should be prioritized because they are likely to be bigger (since the only outgoing HTLC you can add is very tiny).

Thanks for taking the time to detail your point, I think it's really a matter of preference and both could apply, so it's an interesting discussion to have.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think that makes sense to suggest, always being able to receive definitely keeps your channel more healthy more of the time!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I made receiving an HTLC more explicitly the goal of this requirement in afb7313, let me know if that's better.

transaction, its remaining balance doesn't allow it to pay the commitment
transaction fee when receiving or sending a future additional non-dust HTLC
while maintaining its channel reserve. It is recommended that this "fee spike
buffer" can handle twice the current `feerate_per_kw` to ensure predictability
between implementations.
- if it is _not responsible_ for paying the Bitcoin fee:
- SHOULD NOT offer `amount_msat` if, once the remote node adds that HTLC to
its commitment transaction, it cannot pay the fee for the updated local or
remote transaction at the current `feerate_per_kw` while maintaining its
channel reserve.
t-bast marked this conversation as resolved.
Show resolved Hide resolved
t-bast marked this conversation as resolved.
Show resolved Hide resolved
t-bast marked this conversation as resolved.
Show resolved Hide resolved
- MUST offer `amount_msat` greater than 0.
- MUST NOT offer `amount_msat` below the receiving node's `htlc_minimum_msat`
- MUST set `cltv_expiry` less than 500000000.
Expand Down Expand Up @@ -856,6 +869,14 @@ seconds, and the protocol only supports an expiry in blocks.
specification; larger amounts are not necessary, nor wise, during the
bootstrap phase of the network.

The node _responsible_ for paying the Bitcoin fee should maintain a "fee
spike buffer" on top of its reserve to accommodate a future fee increase.
Without this buffer, the node _responsible_ for paying the Bitcoin fee may
reach a state where it is unable to send or receive any non-dust HTLC while
maintaining its channel reserve (because of the increased weight of the
commitment transaction), resulting in a degraded channel. See [#728](https://github.com/lightningnetwork/lightning-rfc/issues/728)
for more details.

### Removing an HTLC: `update_fulfill_htlc`, `update_fail_htlc`, and `update_fail_malformed_htlc`

For simplicity, a node can only remove HTLCs added by the other node.
Expand Down