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

[reliable payments] switch result store clean-up #3131

Merged

Conversation

halseth
Copy link
Contributor

@halseth halseth commented May 28, 2019

This commit makes GetPaymentResult return a channel that should be closed by the caller when the result from the result channel is handled. This instructs the Switch that it is safe to delete the result from its
database.

We make the router close this channel after it has successfully recorded the result, or decided it can re-attempt

This is a follow-up from #2762 and is not critical for the operation of lnd, but the network results would never be deleted from the Switch's store, causing them to take up space. This fixes that by deleting them when we know for sure that the router has handled the result, and won't need it anymore.

There is still a gap that can happen if we crash after the router has acked the result, but before the switch has deleted the payment, but in the worst case it will just leave a result lingering in the store.

2020 update: we do the clean up simply by syncing the control tower with the network result store on startup, garbage collecting the never-to-be-read-again results.

@Roasbeef Roasbeef added database Related to the database/storage of LND htlcswitch P3 might get fixed, nice to have payments Related to invoices/payments refactoring labels Jun 18, 2019
@joostjager
Copy link
Contributor

Is it worth rebasing this and see how much code is left?

@halseth
Copy link
Contributor Author

halseth commented Oct 3, 2019

Should maybe wait for MPP changes to determine whether this is still needed.

@Roasbeef
Copy link
Member

Roasbeef commented May 5, 2020

Do we still care about this?

@halseth
Copy link
Contributor Author

halseth commented Jul 17, 2020

As stated in #3703 the bucket takes up a good chunk of space unnecessarily, so I think it would make sense to finish this one.

@Roasbeef Roasbeef added this to the 0.12.0 milestone Jul 22, 2020
@Roasbeef Roasbeef added the v0.12 label Jul 22, 2020
@Roasbeef
Copy link
Member

@halseth put it back on the milestone, looks like it's gonna take quite a rebase...

@halseth halseth requested review from bhandras and removed request for Roasbeef September 24, 2020 09:32
@halseth
Copy link
Contributor Author

halseth commented Sep 24, 2020

Rebased. Ended up doing it in a much simpler way, that also gets rid of the gap from the original PR...

htlcswitch/payment_result.go Outdated Show resolved Hide resolved
}

var toClean [][]byte
if err := networkResults.ForEach(func(k, _ []byte) error {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This could be further simplified by using a kvdb.RwCursor. Using the cursor there's no need to collect and delete but items can be deleted on the fly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice, didn't know about that! Done 👍

htlcswitch/payment_result_test.go Outdated Show resolved Hide resolved
t.Fatalf("unable to get result: %v", err)
}
if i >= 2 && err != ErrPaymentIDNotFound {
t.Fatalf("expected ErrPaymentIDNotFound, got %v", err)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Similarly, you could use require.Error.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't know if that can be used to match on the exact error?

Copy link
Collaborator

Choose a reason for hiding this comment

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

this should do it: require.Error(t, ErrPaymentIDNotFound, err)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Couldn't get it to work. Looks like require.Error only checks that it is non-nil.

htlcswitch/payment_result_test.go Outdated Show resolved Hide resolved
return err
}

for _, a := range payment.HTLCs {
Copy link
Collaborator

Choose a reason for hiding this comment

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

It seems to me that p which is an InFlightPayment has an Attempts member which holds the same info? (Could be I'm wrong here lacking deeper knowledge of the underlying code.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I deleted that field in the first commit, since it was not used for anything else :)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Need to upgrade my memory to be able the handle three consecutive commits :)

Copy link
Collaborator

@bhandras bhandras left a comment

Choose a reason for hiding this comment

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

A few nits, otherwise LGTM 💡

}
}

if numDeleted == 0 {
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: could be

if numDeleted > 0 {
        log.Infof("Removed %d...)
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done!

t.Fatalf("unable to get result: %v", err)
}
if i >= 2 && err != ErrPaymentIDNotFound {
t.Fatalf("expected ErrPaymentIDNotFound, got %v", err)
Copy link
Collaborator

Choose a reason for hiding this comment

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

this should do it: require.Error(t, ErrPaymentIDNotFound, err)

return err
}

for _, a := range payment.HTLCs {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Need to upgrade my memory to be able the handle three consecutive commits :)

Copy link
Contributor

@cfromknecht cfromknecht left a comment

Choose a reason for hiding this comment

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

LGTM, only one comment about deleting under a cursor. i think this is okay, just wanted to bring it up just in case

}

numDeleted++
if err := cursor.Delete(); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

didn't we have an issue in the past where deleting while iterating caused issues? maybe i'm misremembering the issue tho...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're right, this is still a bug: etcd-io/bbolt#146

When you mention it I remember we had to work around it in btcwallet

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Reverted back to using the original ForEach: 1ff47c6

cc @bhandras

@halseth halseth force-pushed the reliable-payments-switch-gc branch from 44b71b4 to d52eabc Compare October 6, 2020 08:41
That let us clean up handed off payment results, as they will never be
queried again.
@halseth halseth force-pushed the reliable-payments-switch-gc branch from 1ff47c6 to 90a59fe Compare October 6, 2020 08:46
@halseth halseth merged commit 22d7bb1 into lightningnetwork:master Oct 8, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
database Related to the database/storage of LND htlcswitch P3 might get fixed, nice to have payments Related to invoices/payments refactoring v0.12
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants