Author

Topic: Deadlock in key generation due to CCryptoKeyStore (Read 1042 times)

member
Activity: 70
Merit: 18
This is in the latest version in Git.  This is not in the released client.

Creating a new key can freeze the client.  It appears to be much more frequent when there are blocks and transactions to download.

I've been digging in the code to try and find the cause, and I think this is the reason:

CAddressBookDialog::OnButtonNew grabs the cs_vMasterKey, then calls pwalletMain->GetOrReuseKeyFromPool()
GetOrReuseKeyFromPool() calls ReserveKeyFromKeyPool() which attempts to grab cs_main

Meanwhile..

ProcessMessages grabs cs_main and then calls ProcessMessage
ProcessMessage() calls SyncWithWallets, either directly when receiving "tx" or indirectly when receiving a block (via ProcessBlock -> AcceptBlock -> AddToBlockIndex -> SetBestChain -> ConnectBlock -> SyncWithWallets)
SyncWithWallets calls AddToWalletIfInvolvingMe
AddToWalletIfInvolvingMe calls CWallet::IsMine, which calls the global ::IsMine
IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) then calls keystore.GetPubKey
CCryptoKeyStore::GetPubKey then grabs cs_vMasterKey

Deadlock.

Most of the critical sections protect something small well-defined, though I'm not quite sure what cs_main is supposed to be protecting.

I would generate a pull request, except that
1. I have an ugly hack but not a good fix.  I'm not sure what the final strategy is going to be on wallet encryption, and whether the public keys are going to be encrypted too.
2. I am new to git and I am not yet skilled at rebasing commits to include only the changes I want.
Jump to: