-
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
invoices: amp invoices bugfix. #9459
invoices: amp invoices bugfix. #9459
Conversation
Important Review skippedAuto reviews are limited to specific labels. 🏷️ Labels to auto review (1)
Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
bd6443b
to
bef999d
Compare
why is this in 0.18.5? |
my bad. tagged for 0.19 now |
No, 0.18.5 is correct, we'll want it in there as it's an important bug fix. Going to re-tag. |
bef999d
to
5bd4e66
Compare
03df39c
to
72fc2e4
Compare
817bd45
to
5e120a0
Compare
This PR lead to the following feature request: #9463 |
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.
Looks good to me. Left a question, since I'm missing a lot of context.
channeldb/invoices.go
Outdated
@@ -848,7 +838,23 @@ func (k *kvInvoiceUpdater) Finalize(updateType invpkg.UpdateType) error { | |||
return k.storeSettleHodlInvoiceUpdate() | |||
|
|||
case invpkg.CancelInvoiceUpdate: | |||
return k.serializeAndStoreInvoice() | |||
err := k.serializeAndStoreInvoice() |
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.
Couldn't we instead just call k.storeCancelHtlcsUpdate()
? Which makes me think why we didn't do that in the first place? Maybe there's a reason? Missing too much context to be sure...
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.
good call, changed it makes absolutely sense to also persist the AMP state. We never changed the AMP related stuff when canceling an invoice, which is acutally the bug this PR is fixing.
1f689a7
to
8acdba7
Compare
invoice, err := fetchInvoice( | ||
invoiceNum, invoices, []*invpkg.SetID{&invSetID}, false, | ||
invoiceNum, invoices, []*invpkg.SetID{setIDHint}, false, |
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.
Note that this changes behavior slightly as previously we'd pass in a pointer to an empty set id if the hint was nil
whereas now we pass in the nil
which isn't considered the same as an empty set id. PTAL here on how it is used within this package:
Line 1579 in 32cdbb4
if len(setIDs) != 0 && setIDs[0] != nil && |
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 know this is a change to the logic however I think it was a bug in the first place, for the UpdateInvoice
functionality. Because UpdateInvoice will always update a state. Normally we should always have the setID set for AMP invoices. However now that we cancel also the AMP invoice we need to make sure we consider all HTLCs according all setIDs if we cancel the invoice (in case multiple attempts are in the accepted state across multiple setIDs).
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.
moreover if it is not a AMP invoice in the first place this setting is irrelevant anyways:
We already prevent fetching it for non-AMP invoices here in the kv store:
Lines 1541 to 1543 in f4bf99b
if !invoice.IsAMP() { | |
return invoice, nil | |
} |
And also in the sql store:
Lines 1556 to 1569 in f4bf99b
if invoice.IsAMP() { | |
invoiceID := int64(invoice.AddIndex) | |
ampState, ampHtlcs, err := fetchAmpState( | |
ctx, db, invoiceID, setID, fetchAmpHtlcs, | |
) | |
if err != nil { | |
return nil, nil, err | |
} | |
invoice.AMPState = ampState | |
invoice.Htlcs = ampHtlcs | |
return hash, invoice, nil | |
} |
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.
Discussed this offline too. It's probably the best if we remove the HtlcSetBlankModifier
altogether as it is not used anywhere.
channeldb/invoices.go
Outdated
return err | ||
} | ||
|
||
// If this is an AMP invoice, then we'll actually store the rest |
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.
nit: i think this comment could be a bit more descriptive. A reader might be interested in why we're actually updating the amp htlc's in place.
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.
We are calling now k.storeCancelHtlcsUpdate()
directly which makes sense since with might have updated the HTLCs after cancelling the invoice
We now cancel all HTLCs of an AMP invoice as soon as it expires. Otherwise because we mark the invoice as cancelled we would not allow accepted HTLCs to be resolved via the invoiceEventLoop.
8acdba7
to
715cafa
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.
LGTM, nice fix! 🥇
invoice, err := fetchInvoice( | ||
invoiceNum, invoices, []*invpkg.SetID{&invSetID}, false, | ||
invoiceNum, invoices, []*invpkg.SetID{setIDHint}, false, |
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.
Discussed this offline too. It's probably the best if we remove the HtlcSetBlankModifier
altogether as it is not used anywhere.
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 🏆
This PR makes sure that HTLCs in the accepted state will be canceled back if the invoice expires.
However as soon as a sub AMP invoice is settled we do not allow expiring the invoice anyways so canceling the invoice call will fail because we have a check for HTLC which are in the settled state and will return an error, never closing the invoice. This has the positive side-effect that all HTLCs in the accepted state will be cancelled via the
invoiceEventLoop
. However we should definitly fix this behaviour for AMP invoices and also close them, hence not accepting any new payment to it.