diff --git a/src/Makefile.am b/src/Makefile.am --- a/src/Makefile.am +++ b/src/Makefile.am @@ -139,6 +139,7 @@ reverselock.h \ rpc/blockchain.h \ rpc/client.h \ + rpc/mining.h \ rpc/misc.h \ rpc/protocol.h \ rpc/server.h \ diff --git a/src/rpc/mining.h b/src/rpc/mining.h new file mode 100644 --- /dev/null +++ b/src/rpc/mining.h @@ -0,0 +1,21 @@ +// Copyright (c) 2017 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_RPC_MINING_H +#define BITCOIN_RPC_MINING_H + +#include "script/script.h" + +#include + +#include + +class Config; + +/** Generate blocks (mine) */ +UniValue generateBlocks(const Config &config, + std::shared_ptr coinbaseScript, + int nGenerate, uint64_t nMaxTries, bool keepScript); + +#endif diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -3,6 +3,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "rpc/mining.h" #include "amount.h" #include "chain.h" #include "chainparams.h" @@ -109,10 +110,9 @@ request.params.size() > 1 ? request.params[1].get_int() : -1); } -static UniValue generateBlocks(const Config &config, - std::shared_ptr coinbaseScript, - int nGenerate, uint64_t nMaxTries, - bool keepScript) { +UniValue generateBlocks(const Config &config, + std::shared_ptr coinbaseScript, + int nGenerate, uint64_t nMaxTries, bool keepScript) { static const int nInnerLoopCount = 0x100000; int nHeightStart = 0; int nHeightEnd = 0; @@ -177,51 +177,6 @@ return blockHashes; } -static UniValue generate(const Config &config, const JSONRPCRequest &request) { - if (request.fHelp || request.params.size() < 1 || - request.params.size() > 2) { - throw std::runtime_error( - "generate nblocks ( maxtries )\n" - "\nMine up to nblocks blocks immediately (before the RPC call " - "returns)\n" - "\nArguments:\n" - "1. nblocks (numeric, required) How many blocks are generated " - "immediately.\n" - "2. maxtries (numeric, optional) How many iterations to try " - "(default = 1000000).\n" - "\nResult:\n" - "[ blockhashes ] (array) hashes of blocks generated\n" - "\nExamples:\n" - "\nGenerate 11 blocks\n" + - HelpExampleCli("generate", "11")); - } - - int nGenerate = request.params[0].get_int(); - uint64_t nMaxTries = 1000000; - if (request.params.size() > 1) { - nMaxTries = request.params[1].get_int(); - } - - std::shared_ptr coinbaseScript; - GetMainSignals().ScriptForMining(coinbaseScript); - - // If the keypool is exhausted, no script is returned at all. Catch this. - if (!coinbaseScript) { - throw JSONRPCError( - RPC_WALLET_KEYPOOL_RAN_OUT, - "Error: Keypool ran out, please call keypoolrefill first"); - } - - // Throw an error if no script was provided. - if (coinbaseScript->reserveScript.empty()) { - throw JSONRPCError( - RPC_INTERNAL_ERROR, - "No coinbase script available (mining requires a wallet)"); - } - - return generateBlocks(config, coinbaseScript, nGenerate, nMaxTries, true); -} - static UniValue generatetoaddress(const Config &config, const JSONRPCRequest &request) { if (request.fHelp || request.params.size() < 2 || @@ -1092,7 +1047,6 @@ {"mining", "getblocktemplate", getblocktemplate, true, {"template_request"}}, {"mining", "submitblock", submitblock, true, {"hexdata", "parameters"}}, - {"generating", "generate", generate, true, {"nblocks", "maxtries"}}, {"generating", "generatetoaddress", generatetoaddress, true, {"nblocks", "address", "maxtries"}}, {"util", "estimatefee", estimatefee, true, {"nblocks"}}, diff --git a/src/validationinterface.h b/src/validationinterface.h --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -48,7 +48,6 @@ virtual void ResendWalletTransactions(int64_t nBestBlockTime, CConnman *connman) {} virtual void BlockChecked(const CBlock &, const CValidationState &) {} - virtual void GetScriptForMining(std::shared_ptr &){}; virtual void NewPoWValidBlock(const CBlockIndex *pindex, const std::shared_ptr &block){}; friend void ::RegisterValidationInterface(CValidationInterface *); @@ -85,9 +84,6 @@ /** Notifies listeners of a block validation result */ boost::signals2::signal BlockChecked; - /** Notifies listeners that a key for mining is required (coinbase) */ - boost::signals2::signal &)> - ScriptForMining; /** * Notifies listeners that a block which builds directly on our current tip * has been received and connected to the headers tree, though not validated diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -28,15 +28,11 @@ &CValidationInterface::ResendWalletTransactions, pwalletIn, _1, _2)); g_signals.BlockChecked.connect( boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); - g_signals.ScriptForMining.connect( - boost::bind(&CValidationInterface::GetScriptForMining, pwalletIn, _1)); g_signals.NewPoWValidBlock.connect(boost::bind( &CValidationInterface::NewPoWValidBlock, pwalletIn, _1, _2)); } void UnregisterValidationInterface(CValidationInterface *pwalletIn) { - g_signals.ScriptForMining.disconnect( - boost::bind(&CValidationInterface::GetScriptForMining, pwalletIn, _1)); g_signals.BlockChecked.disconnect( boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); g_signals.Broadcast.disconnect(boost::bind( @@ -58,7 +54,6 @@ } void UnregisterAllValidationInterfaces() { - g_signals.ScriptForMining.disconnect_all_slots(); g_signals.BlockChecked.disconnect_all_slots(); g_signals.Broadcast.disconnect_all_slots(); g_signals.Inventory.disconnect_all_slots(); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -12,6 +12,9 @@ #include "dstencode.h" #include "init.h" #include "net.h" +#include "policy/fees.h" +#include "policy/policy.h" +#include "rpc/mining.h" #include "rpc/misc.h" #include "rpc/server.h" #include "timedata.h" @@ -3361,6 +3364,56 @@ return result; } +static UniValue generate(const Config &config, const JSONRPCRequest &request) { + CWallet *const pwallet = GetWalletForJSONRPCRequest(request); + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { + return NullUniValue; + } + + if (request.fHelp || request.params.size() < 1 || + request.params.size() > 2) { + throw std::runtime_error( + "generate nblocks ( maxtries )\n" + "\nMine up to nblocks blocks immediately (before the RPC call " + "returns) to an address in the wallet.\n" + "\nArguments:\n" + "1. nblocks (numeric, required) How many blocks are generated " + "immediately.\n" + "2. maxtries (numeric, optional) How many iterations to try " + "(default = 1000000).\n" + "\nResult:\n" + "[ blockhashes ] (array) hashes of blocks generated\n" + "\nExamples:\n" + "\nGenerate 11 blocks\n" + + HelpExampleCli("generate", "11")); + } + + int num_generate = request.params[0].get_int(); + uint64_t max_tries = 1000000; + if (request.params.size() > 1 && !request.params[1].isNull()) { + max_tries = request.params[1].get_int(); + } + + std::shared_ptr coinbase_script; + pwallet->GetScriptForMining(coinbase_script); + + // If the keypool is exhausted, no script is returned at all. Catch this. + if (!coinbase_script) { + throw JSONRPCError( + RPC_WALLET_KEYPOOL_RAN_OUT, + "Error: Keypool ran out, please call keypoolrefill first"); + } + + // throw an error if no script was provided + if (coinbase_script->reserveScript.empty()) { + throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available"); + } + + return generateBlocks(config, coinbase_script, num_generate, max_tries, + true); +} + // clang-format off static const CRPCCommand commands[] = { // category name actor (function) okSafeMode @@ -3402,6 +3455,8 @@ { "wallet", "walletlock", walletlock, true, {} }, { "wallet", "walletpassphrasechange", walletpassphrasechange, true, {"oldpassphrase","newpassphrase"} }, { "wallet", "walletpassphrase", walletpassphrase, true, {"passphrase","timeout"} }, + + { "generating", "generate", &generate, true, {"nblocks","maxtries"} }, }; // clang-format on diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1003,7 +1003,7 @@ } } - void GetScriptForMining(std::shared_ptr &script) override; + void GetScriptForMining(std::shared_ptr &script); unsigned int GetKeyPoolSize() { // setKeyPool