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

Update MinFinalCltvExpiryDelta default value and activate wumbo #1483

Merged
merged 8 commits into from
Jul 21, 2020

Conversation

t-bast
Copy link
Member

@t-bast t-bast commented Jul 7, 2020

Activate wumbo by default

This is safe as max-funding-satoshis is still set to 16777215 sats, which is the non-wumbo limit.
If users want to increase the maximum channel size, they will now only need to update this configuration value.

Update default minFinalCltvExpiryDelta

See lightning/bolts#785
A value of 9 is a bit too optimistic and could be exploited.

Set minFinalCltvExpiryDelta in invoices

It's important to set minFinalCltvExpiryDelta in the invoices we generate to something bigger than our fulfill-safety-before-timeout-blocks, otherwise we'll close channels whenever a block is produced while we were fulfilling a payment for which we're the final recipient.

NB: @dkrm0 keysend payments will be a problem, because we don't control the minFinalCltvExpiryDelta senders will set and currently have no way of letting them know what value we want. When spec-ing keysend, we should add a tlv to our node_announcement to advertize our minFinalCltvExpiryDelta. Meanwhile we may want to reject keysend payments that are below our minFinalCltvExpiryDelta.

@t-bast t-bast requested a review from pm47 July 7, 2020 13:21
t-bast added 2 commits July 17, 2020 14:16
This is safe as `max-funding-satoshis` is set to 16777215 sats, which is
the non-wumbo limit.

If users want to increase the maximum channel size, they can update this
configuration value.
@t-bast t-bast force-pushed the update-conf-defaults branch from 40e4616 to 3e24f75 Compare July 17, 2020 12:16
Our default fulfill-safety-window is now greater than the spec's default
min-final-expiry-delta in invoices, so we need to explicitly tell payers
what value they must use.

Otherwise we may end up closing channels if a block is produced while we're
waiting for our peer to accept an UpdateFulfillHtlc.
@t-bast t-bast changed the title Update some default configuration values Update MinFinalCltvExpiryDelta default value and activate wumbo Jul 17, 2020
@t-bast t-bast requested a review from pm47 July 21, 2020 09:10
*/
case class SendPaymentRequest(recipientAmount: MilliSatoshi,
paymentHash: ByteVector32,
recipientNodeId: PublicKey,
maxAttempts: Int,
finalExpiryDelta: CltvExpiryDelta = Channel.MIN_CLTV_EXPIRY_DELTA,
fallbackFinalExpiryDelta: CltvExpiryDelta = Channel.MIN_CLTV_EXPIRY_DELTA,
Copy link
Member

Choose a reason for hiding this comment

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

On second thought, I'm not too sure about this. The Channel.MIN_CLTV_EXPIRY_DELTA is spec-defined, that's why it is a constant (and not a configurable value). Why don't we change the definition of PaymentRequest.minFinalCltvExpiryDelta to :

lazy val minFinalCltvExpiryDelta: CltvExpiryDelta = tags.collectFirst {
    case cltvExpiry: PaymentRequest.MinFinalCltvExpiry => cltvExpiry.toCltvExpiryDelta
  } getOrElse(Channel.MIN_CLTV_EXPIRY_DELTA)

We could also keep the PaymentRequest.minFinalCltvExpiryDelta optional, and define a new :

lazy val minFinalCltvExpiryDelta: Option[CltvExpiryDelta] = ...
lazy val minFinalCltvExpiryDeltaWithFallback: CltvExpiryDelta = minFinalCltvExpiryDelta.getOrElse(Channel.MIN_CLTV_EXPIRY_DELTA)

But that seems overkill, since we can always iterate on the tags if we want to know whether the minFinalCltvExpiryDelta was explicitely defined in the payment request or not.

Copy link
Member Author

@t-bast t-bast Jul 21, 2020

Choose a reason for hiding this comment

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

The Channel.MIN_CLTV_EXPIRY_DELTA is spec-defined, that's why it is a constant (and not a configurable value).

This is changing in the spec as we speak :)
We all agreed during yesterday's meeting that hard-coding this in the spec was a bad idea from the start, and we want to remove it entirely.
The last commit of the spec PR now says that writers MUST specify a value in their invoice, and the default value of 18 is only there for backwards-compatibility for readers that receive invoices from legacy wallets/nodes that didn't specify this value.

The goal in the long(er) term is that this will allow us to change this value from an Option[CltvExpiryDelta] to a CltvExpiryDelta once enough nodes have upgraded.

Copy link
Member

Choose a reason for hiding this comment

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

That's fine, let's redefine Channel.MIN_CLTV_EXPIRY_DELTA to 18 and take my first proposal, it is consistent with the decision to make writer MUST define the value?

Copy link
Member Author

Choose a reason for hiding this comment

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

And we do need to keep this fallbackFinalExpiryDelta in these request classes to allow senders to tweak this.
Ideally when you receive an expiryTooSoon error you could guess that you need to provide a higher value here.

Copy link
Member Author

Choose a reason for hiding this comment

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

Or at least the node operator can manually act on this error when the payment fails, whereas if we hide that inside PaymentRequest.scala we lose this ability.

Copy link
Member

Choose a reason for hiding this comment

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

And we do need to keep this fallbackFinalExpiryDelta in these request classes to allow senders to tweak this.

Why would senders need to tweak this?

Ideally when you receive an expiryTooSoon error you could guess that you need to provide a higher value here.
Or at least the node operator can manually act on this error when the payment fails, whereas if we hide that inside PaymentRequest.scala we lose this ability.

If the minFinalExpiryTooSoon is enforced in the payment request, then the only reason this would fail is a disagreement in the current block height, in that case the payment should be retried as-is? Anyway for the use-case you are describing, this isn't a fallback but an override.

Copy link
Member Author

@t-bast t-bast Jul 21, 2020

Choose a reason for hiding this comment

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

Senders may need to tweak this when paying invoices that don't specify this value.

I think older nodes will want to increase the values they accept (given the recent noise about flood and loot) which they can likely do in other implementations by just changing a configuration value, without specifying it in invoices (because the code isn't yet released in implementation to add this to invoices). The only way payers learn that is by the expiry_too_soon error they receive.

I agree that we should remove this fallback value at some point, but I think we should wait a bit before doing this because it removes flexibility (if that case occurs and we removed that parameter, payers can't do anything)...

Copy link
Member Author

Choose a reason for hiding this comment

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

There are some unknowns that may play into this as well, like hodl invoices, so I'm a bit wary when making the API less flexible than before

Copy link
Member

@pm47 pm47 Jul 21, 2020

Choose a reason for hiding this comment

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

Looking deeper into this, I don't think we are handling FinalIncorrectCltvExpiry at all in the payment lifecycle?

We have four possible values for the minFinalCltvExpiry:
1) returned in a FinalIncorrectCltvExpiry
2) manual override (what we are discussing here)
3) in the payment request
4) default suggested value in the spec (9 blocks then, 18 blocks now)

Do we agree on the order of precedence? If we handle the FinalIncorrectCltvExpiry error correctly, I'm not sure we need the manual override.

edit: I'm mistaking FinalIncorrectCltvExpiry with the now deprecated FinalExpiryTooSoon I think. If the final node has no way of telling us what the correct minFinalCltvExpiry value is, then it makes sense to be able to override the value, altough I don't see how it could be used besides testing.

edit 2: Actually yes, it is usable, provided that we define a conservative fallback value in configuration and we it optimistically, which is what this PR does.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks :), once lnd and c-lightning release support for setting it by default in invoices, I think we'll be able to safely remove those and simplify the code

@t-bast t-bast merged commit 625e996 into master Jul 21, 2020
@t-bast t-bast deleted the update-conf-defaults branch July 21, 2020 12:38
dariuskramer pushed a commit that referenced this pull request Jul 21, 2020
Signed-off-by: Donovan Jean <donovan@acinq.fr>
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.

2 participants