Merge pull request #2625 from gavinandresen/walletlock_asio

Use boost::asio::deadline_timer for walletpassphrase timeout
This commit is contained in:
Jeff Garzik
2013-05-30 08:01:22 -07:00
4 changed files with 43 additions and 63 deletions

View File

@@ -84,7 +84,7 @@ Value getinfo(const Array& params, bool fHelp)
obj.push_back(Pair("keypoolsize", pwalletMain->GetKeyPoolSize()));
obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee)));
if (pwalletMain->IsCrypted())
obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime / 1000));
obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime));
obj.push_back(Pair("errors", GetWarnings("statusbar")));
return obj;
}
@@ -1270,56 +1270,11 @@ Value keypoolrefill(const Array& params, bool fHelp)
}
void ThreadTopUpKeyPool(void* parg)
static void LockWallet(CWallet* pWallet)
{
// Make this thread recognisable as the key-topping-up thread
RenameThread("bitcoin-key-top");
pwalletMain->TopUpKeyPool();
}
void ThreadCleanWalletPassphrase(void* parg)
{
// Make this thread recognisable as the wallet relocking thread
RenameThread("bitcoin-lock-wa");
int64 nMyWakeTime = GetTimeMillis() + *((int64*)parg) * 1000;
ENTER_CRITICAL_SECTION(cs_nWalletUnlockTime);
if (nWalletUnlockTime == 0)
{
nWalletUnlockTime = nMyWakeTime;
do
{
if (nWalletUnlockTime==0)
break;
int64 nToSleep = nWalletUnlockTime - GetTimeMillis();
if (nToSleep <= 0)
break;
LEAVE_CRITICAL_SECTION(cs_nWalletUnlockTime);
MilliSleep(nToSleep);
ENTER_CRITICAL_SECTION(cs_nWalletUnlockTime);
} while(1);
if (nWalletUnlockTime)
{
nWalletUnlockTime = 0;
pwalletMain->Lock();
}
}
else
{
if (nWalletUnlockTime < nMyWakeTime)
nWalletUnlockTime = nMyWakeTime;
}
LEAVE_CRITICAL_SECTION(cs_nWalletUnlockTime);
delete (int64*)parg;
LOCK(cs_nWalletUnlockTime);
nWalletUnlockTime = 0;
pWallet->Lock();
}
Value walletpassphrase(const Array& params, bool fHelp)
@@ -1333,9 +1288,6 @@ Value walletpassphrase(const Array& params, bool fHelp)
if (!pwalletMain->IsCrypted())
throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrase was called.");
if (!pwalletMain->IsLocked())
throw JSONRPCError(RPC_WALLET_ALREADY_UNLOCKED, "Error: Wallet is already unlocked.");
// Note that the walletpassphrase is stored in params[0] which is not mlock()ed
SecureString strWalletPass;
strWalletPass.reserve(100);
@@ -1353,9 +1305,12 @@ Value walletpassphrase(const Array& params, bool fHelp)
"walletpassphrase <passphrase> <timeout>\n"
"Stores the wallet decryption key in memory for <timeout> seconds.");
NewThread(ThreadTopUpKeyPool, NULL);
int64* pnSleepTime = new int64(params[1].get_int64());
NewThread(ThreadCleanWalletPassphrase, pnSleepTime);
pwalletMain->TopUpKeyPool();
int64 nSleepTime = params[1].get_int64();
LOCK(cs_nWalletUnlockTime);
nWalletUnlockTime = GetTime() + nSleepTime;
RPCRunLater("lockwallet", boost::bind(LockWallet, pwalletMain), nSleepTime);
return Value::null;
}