From 8a813e2fd53405027be2c1099f76768fb0417b40 Mon Sep 17 00:00:00 2001 From: CryptoManiac Date: Fri, 6 Feb 2015 20:16:21 +0300 Subject: [PATCH] RPC: add new keypoolreset RPC call Similar to keypoolrefill, but performs removal of all unused keys. --- src/bitcoinrpc.cpp | 4 +++- src/bitcoinrpc.h | 1 + src/rpcwallet.cpp | 25 +++++++++++++++++++++++++ src/wallet.cpp | 23 ++++++++++++++--------- src/wallet.h | 2 +- 5 files changed, 44 insertions(+), 11 deletions(-) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index bd711d1..d944b92 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -257,13 +257,14 @@ static const CRPCCommand vRPCCommands[] = { "getaccount", &getaccount, false, false }, { "getaddressesbyaccount", &getaddressesbyaccount, true, false }, { "sendtoaddress", &sendtoaddress, false, false }, - { "mergecoins", &mergecoins, false, false }, + { "mergecoins", &mergecoins, false, false }, { "getreceivedbyaddress", &getreceivedbyaddress, false, false }, { "getreceivedbyaccount", &getreceivedbyaccount, false, false }, { "listreceivedbyaddress", &listreceivedbyaddress, false, false }, { "listreceivedbyaccount", &listreceivedbyaccount, false, false }, { "backupwallet", &backupwallet, true, false }, { "keypoolrefill", &keypoolrefill, true, false }, + { "keypoolreset", &keypoolreset, true, false }, { "walletpassphrase", &walletpassphrase, true, false }, { "walletpassphrasechange", &walletpassphrasechange, false, false }, { "walletlock", &walletlock, true, false }, @@ -1241,6 +1242,7 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector 1) ConvertTo(params[1], true); if (strMethod == "signrawtransaction" && n > 2) ConvertTo(params[2], true); if (strMethod == "keypoolrefill" && n > 0) ConvertTo(params[0]); + if (strMethod == "keypoolreset" && n > 0) ConvertTo(params[0]); if (strMethod == "importaddress" && n > 2) ConvertTo(params[2]); return params; diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h index ecb14f8..9ec5c9e 100644 --- a/src/bitcoinrpc.h +++ b/src/bitcoinrpc.h @@ -191,6 +191,7 @@ extern json_spirit::Value listsinceblock(const json_spirit::Array& params, bool extern json_spirit::Value gettransaction(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value backupwallet(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value keypoolrefill(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value keypoolreset(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value walletpassphrase(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value walletpassphrasechange(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value walletlock(const json_spirit::Array& params, bool fHelp); diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index d1e368c..4090e01 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -1430,6 +1430,31 @@ Value keypoolrefill(const Array& params, bool fHelp) return Value::null; } +Value keypoolreset(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 1) + throw runtime_error( + "keypoolreset [new-size]\n" + "Resets the keypool." + + HelpRequiringPassphrase()); + + unsigned int nSize = max(GetArg("-keypool", 100), 0); + if (params.size() > 0) { + if (params[0].get_int() < 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected valid size"); + nSize = (unsigned int) params[0].get_int(); + } + + EnsureWalletIsUnlocked(); + + pwalletMain->NewKeyPool(nSize); + + if (pwalletMain->GetKeyPoolSize() < nSize) + throw JSONRPCError(RPC_WALLET_ERROR, "Error refreshing keypool."); + + return Value::null; +} + void ThreadTopUpKeyPool(void* parg) { diff --git a/src/wallet.cpp b/src/wallet.cpp index 67a1859..e77fe80 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -2256,7 +2256,7 @@ bool GetWalletFile(CWallet* pwallet, string &strWalletFileOut) // Mark old keypool keys as used, // and generate all new keys // -bool CWallet::NewKeyPool() +bool CWallet::NewKeyPool(unsigned int nSize) { { LOCK(cs_wallet); @@ -2268,14 +2268,19 @@ bool CWallet::NewKeyPool() if (IsLocked()) return false; - int64_t nKeys = max(GetArg("-keypool", 100), (int64_t)0); - for (int i = 0; i < nKeys; i++) + uint64_t nKeys; + if (nSize > 0) + nKeys = nSize; + else + nKeys = max(GetArg("-keypool", 100), 0); + + for (uint64_t i = 0; i < nKeys; i++) { - int64_t nIndex = i+1; + uint64_t nIndex = i+1; walletdb.WritePool(nIndex, CKeyPool(GenerateNewKey())); setKeyPool.insert(nIndex); } - printf("CWallet::NewKeyPool wrote %" PRId64 " new keys\n", nKeys); + printf("CWallet::NewKeyPool wrote %" PRIu64 " new keys\n", nKeys); } return true; } @@ -2291,21 +2296,21 @@ bool CWallet::TopUpKeyPool(unsigned int nSize) CWalletDB walletdb(strWalletFile); // Top up key pool - unsigned int nTargetSize; + uint64_t nTargetSize; if (nSize > 0) nTargetSize = nSize; else - nTargetSize = max(GetArg("-keypool", 100), 0LL); + nTargetSize = max(GetArg("-keypool", 100), 0); while (setKeyPool.size() < (nTargetSize + 1)) { - int64_t nEnd = 1; + uint64_t nEnd = 1; if (!setKeyPool.empty()) nEnd = *(--setKeyPool.end()) + 1; if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey()))) throw runtime_error("TopUpKeyPool() : writing generated key failed"); setKeyPool.insert(nEnd); - printf("keypool added key %" PRId64 ", size=%" PRIszu "\n", nEnd, setKeyPool.size()); + printf("keypool added key %" PRIu64 ", size=%" PRIszu "\n", nEnd, setKeyPool.size()); } } return true; diff --git a/src/wallet.h b/src/wallet.h index 9dfc56e..ec937ec 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -228,7 +228,7 @@ public: std::string SendMoney(CScript scriptPubKey, int64_t nValue, CWalletTx& wtxNew, bool fAskFee=false); std::string SendMoneyToDestination(const CTxDestination &address, int64_t nValue, CWalletTx& wtxNew, bool fAskFee=false); - bool NewKeyPool(); + bool NewKeyPool(unsigned int nSize = 0); bool TopUpKeyPool(unsigned int nSize = 0); int64_t AddReserveKey(const CKeyPool& keypool); void ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool); -- 1.7.1