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

features+invoices: force MPP payload inclusion for non-keysend payments #4752

Merged
merged 7 commits into from
Nov 26, 2020

Conversation

Roasbeef
Copy link
Member

@Roasbeef Roasbeef commented Nov 7, 2020

In this PR, we move to start rejecting any normal payments that aren't keysend, if they don't also include the MPP invoice payload. With this change, we require that some sort of e2e secret (either the payment addr or the keysend pre-image) is present in a payload before we'll accept the payment.

In other words, we move to start requiring the payment addr feature bit in the invoices we produce. With this change, if a user attempts to pay one of our invoices (assuming they're also an lnd node), then they'll receive an error when they attempt to pay. At this point, most lnd nodes should be on v0.11 at this point, and this change will notify any lagging wallet authors to update, as these payments are generally more secure.

Fixes #4661 ?

@Roasbeef Roasbeef added safety General label for issues/PRs related to the safety of using the software payments Related to invoices/payments labels Nov 7, 2020
@Roasbeef Roasbeef added this to the 0.12.0 milestone Nov 7, 2020
Copy link
Contributor

@halseth halseth left a comment

Choose a reason for hiding this comment

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

utACK

invoices/update.go Show resolved Hide resolved
// payment, then we'll return an error that the payment addr was wrong,
// since we require it for improved e2e payment security.
if ctx.mpp == nil {
return nil, ctx.failRes(ResultAddressMismatch), nil
Copy link
Contributor

Choose a reason for hiding this comment

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

i'm not sure this is the right error to return. in this case the sender sent a legacy payment, but they are getting errors about a feature they don't have implemented (otherwise they would have used mpp). presumably if they haven't implemented mpp they haven't implemented mpp errors, so this will be interpreted as unknown. perhaps incorrect-payment-details is more appropriate? should probably coordinate with the other implementations to ensure we all agree on how to handle it

Copy link
Member Author

Choose a reason for hiding this comment

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

These errors are mainly just for proper internal logging and tests. The only errors we ever return that're soured from the invoice registry are: lnwire.FailMPPTimeout and IncorrectPaymentDetails: https://github.com/lightningnetwork/lnd/blob/master/htlcswitch/link.go#L1257

@Roasbeef
Copy link
Member Author

PTAL @cfromknecht

@Roasbeef
Copy link
Member Author

Looking into the new itest failure.

@halseth halseth removed the request for review from joostjager November 24, 2020 10:49
Copy link
Contributor

@halseth halseth left a comment

Choose a reason for hiding this comment

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

Latest iteration looks good IMO👍

// we'll permit it to pass.
_, isKeySend := ctx.customRecords[record.KeySendType]
invoiceFeatures := inv.Terms.Features
paymentAddrRequired := invoiceFeatures.HasFeature(
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 we need a new method here: RequiresFeature. HasFeature returns true if either are set.

Copy link
Member Author

Choose a reason for hiding this comment

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

Added in the latest version! Also added a test for both the new method, as well as the positive path (for legacy invoices) in this area as well.

@cfromknecht
Copy link
Contributor

also needs squash!

@Roasbeef Roasbeef force-pushed the require-payment-addr branch from c571ce8 to 5a8cd7e Compare November 25, 2020 03:57
@Roasbeef
Copy link
Member Author

Pushed up new version that should pass that itests, and which also addresses Conner's latest comments.

feature ^= 1
}

return fv.IsSet(feature)
Copy link
Contributor

Choose a reason for hiding this comment

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

alternatively could be fv.IsSet(feature&0xfe) which clears the lowest bit

invoices/update.go Outdated Show resolved Hide resolved

// mpp sets the MPP fields on the request if true, otherwise submits a
// regular payment.
mpp bool
Copy link
Contributor

Choose a reason for hiding this comment

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

doesn't this mean we are no longer testing legacy payments? or do we need to do this because our invoices now require them?

In this commit, we move to start requiring the payment addr feature bit
in the invoices we produce. With this change, if a user attempts to pay
one of our invoices (assuming they're also an lnd node), then they'll
receive an error when they attempt to pay. At this point, *most* lnd
nodes should be on v0.11 at this point, and this change will notify any
lagging wallet authors to update, as these payments are generally more
secure.
In this commit, we add a new RequiresFeature method to the feature
vector struct. This method allows us to check if the set of features
we're examining *require* that the even portion of a bit pair be set.
This can be used to check if new behavior should be allowed (after we
flip new bits to be required) for existing contexts.
In this commit, we move to start rejecting any normal payments that
aren't keysend, if they don't also include the MPP invoice payload. With
this change, we require that some sort of e2e secret (either the payment
addr or the keysend pre-image) is present in a payload before we'll
accept the payment.

The second portion of the commit also updates all current tests in the
package. We kept the base `TestSettleInvoice` test in-tact as it still
exercises some useful behavior. However, we've removed all cases that
allow an overpayment, as the new MPP logic doesn't allow overpayment for
various reasons. In addition to this, some of the returned errors are
slightly different, tho the actual behavior is equivalent.
In this commit, we extend the `BuildRoute` method and RPC on the router
sub-server to accept a raw payment address which will be included as
part of an MPP payload for the finla hop. This change actually also
allows users to craft their own MPP paths using BuildRoute+SendToRoute.
Our primary goal however, was to fix some broken itests since we now
require the payAddr to be present for ALL payments other than key send
payments.
With this change ListInvoices will return the payment addr, and the
response to AddInvoice will as well.
It needs to include the MPP payload  now.
@Roasbeef Roasbeef force-pushed the require-payment-addr branch from d74ad5e to 4e079d1 Compare November 26, 2020 00:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
payments Related to invoices/payments safety General label for issues/PRs related to the safety of using the software
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Flag for mandatory payment_addr
4 participants