-
Notifications
You must be signed in to change notification settings - Fork 38.7k
CReserveKey should not allow passive key re-use, debug assert in destructor #15796
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
Conversation
|
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsNo conflicts as of last run. |
|
secp unit test failure, reported here in one build: bitcoin-core/secp256k1#610 restarted. |
|
I think the whole Line 2835 in 2a191b4
Line 2894 in 2a191b4
bitcoin/src/wallet/rpcwallet.cpp Line 340 in 2a191b4
I don't know whether that could cause problems for users or client applications. For example a client that tries to create a transaction, hits an error, retries in a loop and burns many keypool keys. |
|
Granted this is an extremely timid change, but you can make more keys. You cannot make more privacy when this fails. I'll let others chime in before I try to nibble at the edges and make sure these |
Yep. To be clear, I'm not NACKing this. Just trying to figure out what the least bad option is. |
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.
utACK eac5438108339a65f3dd6d9cce06404167736c2e. Seems sensible to choose the wrong thing you can recover from if you're choosing between doing two potentially wrong things.
I guess the least "timid change" would be unconditionally asserting or throwing when KeepKey or ReturnKey aren't called. But other less timid options would be logging errors when they aren't called, or asserting that they are called in --debug builds.
But current change does seem like this simplest option to implement, and I think it's an improvement.
|
assert seems better IMO |
|
Needs documentation updated (after rebase) |
|
Deciding if it's worth the rebase. There are as many opinions here. I'm also fine with an assert to be honest. |
You mean |
|
Sure, something like that. |
|
@jnewbery @ryanofsky are you guys ok with an assert instead? I'd rather do something than let this languish, and it seems reasonable. |
I'd prefer the assert, but I think the current change is also an improvement. I'd be happy with either change. |
I would prefer to do this. |
|
TIL about debug builds. Added an assert behind that, and a print otherwise telling the user to report it. |
|
pushed fancier reporting error log courtesy of @MarcoFalke |
ryanofsky
left a comment
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.
utACK 735518bbeb17f61b3a79eae503b0efb17089acd7. PR title needs to be updated (in the future I think it's better to close and open a new PR if you implement an alternate approach so discussion makes more sense and it's easy to look back and see what the rejected alternatives looked like). Also in the future, the CHECK macro proposed in #16136 might simplify this more.
|
Having second-thoughts, mea culpa. Basically anytime there's a wallet error of any sort, you need to make sure you handle it and ReturnKey. This happens in dozens of places, including in Opened an alternative here: #16208 |
|
closing this one for now |
|
This pr is closed, and the alternate implementation in #16208 seems good, but I just wanted to note that it would be possible to check with compile errors, not just runtime asserts that the |
|
@ryanofsky interesting! |
…Transaction e10e1e8 Restrict lifetime of ReserveDestination to CWallet::CreateTransaction (Gregory Sanders) d9ff862 CreateTransaction calls KeepDestination on ReserveDestination before success (Gregory Sanders) Pull request description: The typical usage pattern of `ReserveDestination` is to explicitly `KeepDestination`, or `ReturnDestination` when it's detected it will not be used. Implementers such as myself may fail to complete this pattern, and could result in key re-use: #15557 (comment) Since ReserveDestination is currently only used directly in the `CreateTransaction`/`CommitTransaction` flow(or fee bumping where it's just used in `CreateTransaction`), I instead make the assumption that if a transaction is returned by `CreateTransaction` it's highly likely that it will be accepted by the caller, and the `ReserveDestination` kept. This simplifies the API as well. There are very few cases where this would not be the case which may result in keys being burned. Those failure cases appear to be: `CommitTransaction` failing to get the transaction into the mempool Belt and suspenders check in `WalletModel::prepareTransaction` Alternative to #15796 ACKs for top commit: achow101: ACK e10e1e8 Reviewed the diff stevenroose: utACK e10e1e8 meshcollider: utACK e10e1e8 Tree-SHA512: 78d047a00f39ab41cfa297052cc1e9c224d5f47d3d2299face650d71827635de077ac33fb4ab9f7dc6fc5a27f4a68415a1bc9ca33a3cb09a78f4f15b2a48411b
… CreateTransaction e10e1e8 Restrict lifetime of ReserveDestination to CWallet::CreateTransaction (Gregory Sanders) d9ff862 CreateTransaction calls KeepDestination on ReserveDestination before success (Gregory Sanders) Pull request description: The typical usage pattern of `ReserveDestination` is to explicitly `KeepDestination`, or `ReturnDestination` when it's detected it will not be used. Implementers such as myself may fail to complete this pattern, and could result in key re-use: bitcoin#15557 (comment) Since ReserveDestination is currently only used directly in the `CreateTransaction`/`CommitTransaction` flow(or fee bumping where it's just used in `CreateTransaction`), I instead make the assumption that if a transaction is returned by `CreateTransaction` it's highly likely that it will be accepted by the caller, and the `ReserveDestination` kept. This simplifies the API as well. There are very few cases where this would not be the case which may result in keys being burned. Those failure cases appear to be: `CommitTransaction` failing to get the transaction into the mempool Belt and suspenders check in `WalletModel::prepareTransaction` Alternative to bitcoin#15796 ACKs for top commit: achow101: ACK e10e1e8 Reviewed the diff stevenroose: utACK e10e1e8 meshcollider: utACK e10e1e8 Tree-SHA512: 78d047a00f39ab41cfa297052cc1e9c224d5f47d3d2299face650d71827635de077ac33fb4ab9f7dc6fc5a27f4a68415a1bc9ca33a3cb09a78f4f15b2a48411b
…Transaction e10e1e8 Restrict lifetime of ReserveDestination to CWallet::CreateTransaction (Gregory Sanders) d9ff862 CreateTransaction calls KeepDestination on ReserveDestination before success (Gregory Sanders) Pull request description: The typical usage pattern of `ReserveDestination` is to explicitly `KeepDestination`, or `ReturnDestination` when it's detected it will not be used. Implementers such as myself may fail to complete this pattern, and could result in key re-use: bitcoin/bitcoin#15557 (comment) Since ReserveDestination is currently only used directly in the `CreateTransaction`/`CommitTransaction` flow(or fee bumping where it's just used in `CreateTransaction`), I instead make the assumption that if a transaction is returned by `CreateTransaction` it's highly likely that it will be accepted by the caller, and the `ReserveDestination` kept. This simplifies the API as well. There are very few cases where this would not be the case which may result in keys being burned. Those failure cases appear to be: `CommitTransaction` failing to get the transaction into the mempool Belt and suspenders check in `WalletModel::prepareTransaction` Alternative to bitcoin/bitcoin#15796 ACKs for top commit: achow101: ACK e10e1e8 Reviewed the diff stevenroose: utACK e10e1e8 meshcollider: utACK e10e1e8 Tree-SHA512: 78d047a00f39ab41cfa297052cc1e9c224d5f47d3d2299face650d71827635de077ac33fb4ab9f7dc6fc5a27f4a68415a1bc9ca33a3cb09a78f4f15b2a48411b
The typical usage pattern of
CReserveKeyis to explicitlyKeepKey, orReturnKeywhen it's detected it will not be used.Implementers such as myself may fail to complete this pattern, and could result in key re-use: #15557 (comment)
Have it assert on debug builds when it's not dealt with, and log an important sounding message otherwise.