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

contractcourt: stop lnd when received witness is empty #7811

Merged
merged 4 commits into from Oct 31, 2023

Conversation

yyforyongyu
Copy link
Collaborator

This is the first commit from #7615. Making a PR for it so affected users can apply the patch first.

This commit adds a length check in isPreimageSpend to make sure it won't ever panic and adds a unit test to verify it.

Copy link
Collaborator

@morehouse morehouse left a comment

Choose a reason for hiding this comment

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

LGTM with a couple nits.


// witnessSpendLocal is the remote's witness used to spend the HTLC via
// the second stage success tx path on the remote commitment.
witnessSpendLocal := wire.TxWitness{
Copy link
Collaborator

Choose a reason for hiding this comment

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

Shouldn't we call this witnessSpendRemote?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

named it to witnessSpendSuccess instead. So what I want to differentiate here is not local vs remote but how the preimage is revealed - either via the second stage success tx, or a direct spend. And in the test case setup we then start paying attention to whether it's a local view or a remote view.


// witnessSpendDirect is the remote's witness used to spend the HTLC
// via the preimage path on the local commitment.
witnessSpendDirect := wire.TxWitness{
Copy link
Collaborator

Choose a reason for hiding this comment

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

How about witnessSpendLocal?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The direct spend can happen for both local and remote tho.

Copy link
Collaborator

Choose a reason for hiding this comment

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

You are right in general the Preimage Spent can happen by us on the remote, but refering to the naming of the file htlc_timeout_resolver their are only two possibilities for the preimage spent. Either on the remote via the witnessSpendSuccess or on our local via the witnessSpendLocal ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Updated the tests to more clearly express the testing objects.

Copy link
Collaborator

Choose a reason for hiding this comment

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

looks great now!

Comment on lines 108 to 109
// on the local commitment transaction for an outgoing HTLC that is
// swept on-chain by us with pre-image.
Copy link
Collaborator

Choose a reason for hiding this comment

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

If it is the local commitment tx, and we are sweeping the pre-image path, then it must be an incoming HTLC. An outgoing htlc on our commitment tx can only be swept by us via the timeout path.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

updated.

@Crypt-iQ
Copy link
Collaborator

I don't think this should be done, we should instead figure out why bitcoind isn't serving witness data and, if we're able to, refuse to startup. Also this skips potentially notifying on a preimage spend if the bitcoind were to later right itself via user running -reindex.

@morehouse
Copy link
Collaborator

I don't think this should be done, we should instead figure out why bitcoind isn't serving witness data and, if we're able to, refuse to startup. Also this skips potentially notifying on a preimage spend if the bitcoind were to later right itself via user running -reindex.

This PR seems valuable to me on its own -- why shouldn't we do a bounds check before accessing the array element? We already do the bounds check for the remote commitment.

Whether this PR fixes the root cause is orthogonal.

@Crypt-iQ
Copy link
Collaborator

This PR seems valuable to me on its own -- why shouldn't we do a bounds check before accessing the array element? We already do the bounds check for the remote commitment.

I think the PR is fine after we've fixed the issue. I'd prefer that before it's actually fixed, we fail loudly on missing witness data. Otherwise continuing rather than panic means a -reindex won't extract the preimage on-chain.

Whether this PR fixes the root cause is orthogonal.

I don't agree because if we fix this immediately, we may never fix the root cause as it'll fail silently

@yyforyongyu
Copy link
Collaborator Author

I think the PR is fine after we've fixed the issue. I'd prefer that before it's actually fixed, we fail loudly on missing witness data.

Yeah we should fix it, tho I don't think it can be fixed inside lnd. And I also don't think we should let it go silently. I've added an error log in the latest push, but don't think it's enough. If we are sure it's an issue from bitcoind, we need to panic there with some info like reindex your bitcoind since it's very critical to have a healthy chain backend.

@yyforyongyu yyforyongyu changed the title contractcourt: make sure isPreimageSpend won't panic contractcourt: stop lnd when received witness is empty Aug 18, 2023
@yyforyongyu yyforyongyu force-pushed the fix-panix branch 4 times, most recently from 91cb102 to 90010c9 Compare August 25, 2023 00:43
@yyforyongyu yyforyongyu added security General label for issues/PRs related to the security of the software backend Related to the node backend software/interface (e.g. btcd, bitcoin-core) bitcoind Bitcoin Core backend P2 should be fixed if one has time labels Sep 19, 2023
@yyforyongyu yyforyongyu requested review from Crypt-iQ and removed request for Crypt-iQ October 9, 2023 07:11
@lightninglabs-deploy
Copy link

@Crypt-iQ: review reminder
@yyforyongyu, remember to re-request review from reviewers when ready

Copy link
Collaborator

@ziggie1984 ziggie1984 left a comment

Choose a reason for hiding this comment

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

Great work yy 🤝, had some minor nits. Gracefully shutting down LND when no witness data is present makes a lot of sense. Especially because we cannot guarantee the user setting -rpcserialversion .


// witnessSpendDirect is the remote's witness used to spend the HTLC
// via the preimage path on the local commitment.
witnessSpendDirect := wire.TxWitness{
Copy link
Collaborator

Choose a reason for hiding this comment

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

You are right in general the Preimage Spent can happen by us on the remote, but refering to the naming of the file htlc_timeout_resolver their are only two possibilities for the preimage spent. Either on the remote via the witnessSpendSuccess or on our local via the witnessSpendLocal ?

contractcourt/htlc_timeout_resolver_test.go Outdated Show resolved Hide resolved
chainntnfs/interface.go Show resolved Hide resolved
chainntnfs/txnotifier.go Outdated Show resolved Hide resolved
@yyforyongyu yyforyongyu force-pushed the fix-panix branch 2 times, most recently from a71591c to e94af84 Compare October 30, 2023 06:26
@yyforyongyu yyforyongyu changed the base branch from master to 0-18-staging October 30, 2023 06:26
Copy link
Collaborator

@ziggie1984 ziggie1984 left a comment

Choose a reason for hiding this comment

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

Base-Branch can be changed to master.

LGTM 🚀

@Roasbeef Roasbeef changed the base branch from 0-18-staging to master October 30, 2023 17:44
This commit adds a length check in `isPreimageSpend` to make sure it
won't ever panic and adds a unit test to verify it.
This commit adds a check when receiving transactions from
`BitcoindClient` so an error is returned when empty witness is found.
This commit uses `Criticalf` to gracefully stop `lnd` when the received
witness data is empty.
@Roasbeef Roasbeef added this to the v0.18.0 milestone Oct 31, 2023
@Roasbeef Roasbeef merged commit eb5fc0c into lightningnetwork:master Oct 31, 2023
23 of 26 checks passed
@yyforyongyu yyforyongyu deleted the fix-panix branch November 1, 2023 08:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend Related to the node backend software/interface (e.g. btcd, bitcoin-core) bitcoind Bitcoin Core backend P2 should be fixed if one has time security General label for issues/PRs related to the security of the software
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants