-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
channeldb: index payments by payment addr, use payment hash as fallback #4285
channeldb: index payments by payment addr, use payment hash as fallback #4285
Conversation
One thought that came up: (hodl) keysend payments and AMP payments can be settled by payment address. But how does that work for recurring payments to the same address? How to keep those apart when you want to settle or cancel? I think the |
58ffb70
to
46ebc79
Compare
channeldb/invoices.go
Outdated
@@ -538,7 +553,9 @@ func (d *DB) InvoicesAddedSince(sinceAddIndex uint64) ([]Invoice, error) { | |||
// full invoice is returned. Before setting the incoming HTLC, the values | |||
// SHOULD be checked to ensure the payer meets the agreed upon contractual | |||
// terms of the payment. | |||
func (d *DB) LookupInvoice(paymentHash [32]byte) (Invoice, error) { | |||
func (d *DB) LookupInvoice(paymentHash [32]byte, | |||
payAddr *[32]byte) (Invoice, error) { |
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.
Is there a use case for specifying both?
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.
Or if both are specified, is a sanity check useful to see if hash is always present and pointing to the same invoice if addr is present too?
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 reason to use both is so that we don't have to add a migration for existing invoices. with AMP the hash won't align with any particular invoice, but this wil be worked around by providing a nil hash in the InvoiceRef
.
if we do a full migration we'd end up supporting either (hash, nil)
or (nil, pay_addr)
. if we don't, then we need to support (hash, nil)
, (nil, pay_addr)
, or (hash, pay_addr)
, where the latter has a sanity check that they point to the same invoice.
atm, there isn't really a business use case for doing the full migration, it would only serve to clean up this bit of code. this may change in the in the future tho (if we begin exposing invoice lookups by payment addr and we want to expose these slightly older invoices), but it is still possible to do this migration retroactively when that time comes. it is not terribly difficult, but it is time consuming in the critical path
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.
InvoiceRef
added, supporting (hash, nil)
and (hash, pay_addr)
. the final variant will be added once the related AMP changes go in
2c6e0b8
to
18d887a
Compare
02fc031
to
d4eb6f3
Compare
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.
Great improvement with InvoiceRef
!
err = tx.DeleteTopLevelBucket(graphMetaBucket) | ||
if err != nil && err != kvdb.ErrBucketNotFound { | ||
return err | ||
for _, tlb := range topLevelBuckets { |
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.
If we're removing everything, can't it be a for each on the tx?
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.
it's less atomic, but also only used for testing afaia, what would we gain?
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.
Hmm so it should really be moved to a _test.go
file then.
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.
Yeah it's something left over from super early development, when the easiest thing to do was just delete the entire database and start over lol.
// hash, but pre 0.8 invoices do not have one at all. When this value is | ||
// known it will be used as the primary identifier, falling back to | ||
// payHash if no value is known. | ||
payAddr *[32]byte |
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.
Not necessarily for this PR, but I can see an advantage of making an lntypes.Hash
style datatype for payment address, especially if we are going to use it a lot
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.
yes i've been thinking maybe we should, but held off because we don't use it for anything other than comparing equality. definitely something we can look into tho, it would be nice if they were unified
d4eb6f3
to
920bfd0
Compare
err = tx.DeleteTopLevelBucket(graphMetaBucket) | ||
if err != nil && err != kvdb.ErrBucketNotFound { | ||
return err | ||
for _, tlb := range topLevelBuckets { |
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.
Hmm so it should really be moved to a _test.go
file then.
920bfd0
to
532b1a4
Compare
Test failure on travis:
Not sure if related. |
New trigger in the error log filtration for the itests:
|
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.
LGTM 🗿
Merge pending resolution of those two build issues I mentioned (log one is easy, other one may just be something else entirely, and thus out of scope).
channeldb/invoices.go
Outdated
@@ -142,6 +142,32 @@ const ( | |||
amtPaidType tlv.Type = 13 | |||
) | |||
|
|||
// InvoiceRef is an identifier for invoices supporting queries by payment hash. |
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.
me gusta
532b1a4
to
dacdbce
Compare
This line was incorrectly moved when the migtest package was created for migration 12. This PR introduces a negative test for CreateTLB which surfaced this.
This commit creates a generic migration for creating top-level buckets.
dacdbce
to
0730e39
Compare
Neutrino can get slow towards the end of the itests.
a072b5a
to
152d153
Compare
Getting an error after this merge when trying to build lnd.
|
We recently renamed kvdb.ReadBucket to kvdb.RBucket in lightningnetwork#4252, but this was not detected in lightningnetwork#4285 since this new code didn't produce a conflict.
This PR adds a new persistent index on invoices to allow efficient
lookups and updates by payment address. This is stepping stone
to enable AMP payments where the payment hash will not be
associated with the target invoice.
Since 0.9, all new invoices include a random payment address,
however older invoices do not have this value. New invoices will
be added to the payment address index on a rolling basis, but
the payment hash index will continue to serve as a fallback in case
the target invoice was created prior to this commit. As such,
no migration is needed for invoices created prior to this commit,
but we include one to bump the db version number and initialize
the top-level index bucket.
This also unblocks #4167, since it allows us to insert a random
payment address for experimental keysend payments. In the future,
where keysend is rolled into the final AMP proposal, this ensures that
all keysend (experimental or otherwise) have a payment address
associated with the invoice. This is desired since we will be using
payment addresses entirely to identify and update AMP payments, so
we ensure the code paths between AMP and legacy keysend are
identical.
Further off, once payment addresses are required, we can stop inserting
invoices into the payment hash index entirely. Currently however, we rely
on invoices being indexed to support other operations, e.g. hodl settle/cancel
or legacy senders that don't understand MPP.