diff options
Diffstat (limited to 'src/rpc/mining.cpp')
-rw-r--r-- | src/rpc/mining.cpp | 185 |
1 files changed, 96 insertions, 89 deletions
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 996b7f9cbd..b63ee22889 100644 --- 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 "base58.h" #include "amount.h" #include "chain.h" #include "chainparams.h" @@ -68,7 +69,7 @@ UniValue GetNetworkHashPS(int lookup, int height) { arith_uint256 workDiff = pb->nChainWork - pb0->nChainWork; int64_t timeDiff = maxTime - minTime; - return (int64_t)(workDiff.getdouble() / timeDiff); + return workDiff.getdouble() / timeDiff; } UniValue getnetworkhashps(const UniValue& params, bool fHelp) @@ -93,59 +94,12 @@ UniValue getnetworkhashps(const UniValue& params, bool fHelp) return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1); } -UniValue getgenerate(const UniValue& params, bool fHelp) +UniValue generateBlocks(boost::shared_ptr<CReserveScript> coinbaseScript, int nGenerate, uint64_t nMaxTries, bool keepScript) { - if (fHelp || params.size() != 0) - throw runtime_error( - "getgenerate\n" - "\nReturn if the server is set to generate coins or not. The default is false.\n" - "It is set with the command line argument -gen (or " + std::string(BITCOIN_CONF_FILENAME) + " setting gen)\n" - "It can also be set with the setgenerate call.\n" - "\nResult\n" - "true|false (boolean) If the server is set to generate coins or not\n" - "\nExamples:\n" - + HelpExampleCli("getgenerate", "") - + HelpExampleRpc("getgenerate", "") - ); - - LOCK(cs_main); - return GetBoolArg("-gen", DEFAULT_GENERATE); -} - -UniValue generate(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() < 1 || params.size() > 1) - throw runtime_error( - "generate numblocks\n" - "\nMine blocks immediately (before the RPC call returns)\n" - "\nNote: this function can only be used on the regtest network\n" - "\nArguments:\n" - "1. numblocks (numeric, required) How many blocks are generated immediately.\n" - "\nResult\n" - "[ blockhashes ] (array) hashes of blocks generated\n" - "\nExamples:\n" - "\nGenerate 11 blocks\n" - + HelpExampleCli("generate", "11") - ); - - if (!Params().MineBlocksOnDemand()) - throw JSONRPCError(RPC_METHOD_NOT_FOUND, "This method can only be used on regtest"); - + static const int nInnerLoopCount = 0x10000; int nHeightStart = 0; int nHeightEnd = 0; int nHeight = 0; - int nGenerate = params[0].get_int(); - - boost::shared_ptr<CReserveScript> 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)"); { // Don't keep cs_main locked LOCK(cs_main); @@ -165,10 +119,15 @@ UniValue generate(const UniValue& params, bool fHelp) LOCK(cs_main); IncrementExtraNonce(pblock, chainActive.Tip(), nExtraNonce); } - while (!CheckProofOfWork(pblock->GetHash(), pblock->nBits, Params().GetConsensus())) { - // Yes, there is a chance every nonce could fail to satisfy the -regtest - // target -- 1 in 2^(2^32). That ain't gonna happen. + while (nMaxTries > 0 && pblock->nNonce < nInnerLoopCount && !CheckProofOfWork(pblock->GetHash(), pblock->nBits, Params().GetConsensus())) { ++pblock->nNonce; + --nMaxTries; + } + if (nMaxTries == 0) { + break; + } + if (pblock->nNonce == nInnerLoopCount) { + continue; } CValidationState state; if (!ProcessNewBlock(state, Params(), NULL, pblock, true, NULL)) @@ -176,54 +135,82 @@ UniValue generate(const UniValue& params, bool fHelp) ++nHeight; blockHashes.push_back(pblock->GetHash().GetHex()); - //mark script as important because it was used at least for one coinbase output - coinbaseScript->KeepScript(); + //mark script as important because it was used at least for one coinbase output if the script came from the wallet + if (keepScript) + { + coinbaseScript->KeepScript(); + } } return blockHashes; } -UniValue setgenerate(const UniValue& params, bool fHelp) +UniValue generate(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( - "setgenerate generate ( genproclimit )\n" - "\nSet 'generate' true or false to turn generation on or off.\n" - "Generation is limited to 'genproclimit' processors, -1 is unlimited.\n" - "See the getgenerate call for the current setting.\n" + "generate numblocks ( maxtries )\n" + "\nMine up to numblocks blocks immediately (before the RPC call returns)\n" "\nArguments:\n" - "1. generate (boolean, required) Set to true to turn on generation, off to turn off.\n" - "2. genproclimit (numeric, optional) Set the processor limit for when generation is on. Can be -1 for unlimited.\n" + "1. numblocks (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" - "\nSet the generation on with a limit of one processor\n" - + HelpExampleCli("setgenerate", "true 1") + - "\nCheck the setting\n" - + HelpExampleCli("getgenerate", "") + - "\nTurn off generation\n" - + HelpExampleCli("setgenerate", "false") + - "\nUsing json rpc\n" - + HelpExampleRpc("setgenerate", "true, 1") + "\nGenerate 11 blocks\n" + + HelpExampleCli("generate", "11") ); - if (Params().MineBlocksOnDemand()) - throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Use the generate method instead of setgenerate on this network"); + int nGenerate = params[0].get_int(); + uint64_t nMaxTries = 1000000; + if (params.size() > 1) { + nMaxTries = params[1].get_int(); + } - bool fGenerate = true; - if (params.size() > 0) - fGenerate = params[0].get_bool(); + boost::shared_ptr<CReserveScript> coinbaseScript; + GetMainSignals().ScriptForMining(coinbaseScript); - int nGenProcLimit = GetArg("-genproclimit", DEFAULT_GENERATE_THREADS); - if (params.size() > 1) - { - nGenProcLimit = params[1].get_int(); - if (nGenProcLimit == 0) - fGenerate = false; + // 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(coinbaseScript, nGenerate, nMaxTries, true); +} + +UniValue generatetoaddress(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() < 2 || params.size() > 3) + throw runtime_error( + "generatetoaddress numblocks address (maxtries)\n" + "\nMine blocks immediately to a specified address (before the RPC call returns)\n" + "\nArguments:\n" + "1. numblocks (numeric, required) How many blocks are generated immediately.\n" + "2. address (string, required) The address to send the newly generated bitcoin to.\n" + "3. 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 to myaddress\n" + + HelpExampleCli("generatetoaddress", "11 \"myaddress\"") + ); + + int nGenerate = params[0].get_int(); + uint64_t nMaxTries = 1000000; + if (params.size() > 2) { + nMaxTries = params[2].get_int(); } - mapArgs["-gen"] = (fGenerate ? "1" : "0"); - mapArgs ["-genproclimit"] = itostr(nGenProcLimit); - GenerateBitcoins(fGenerate, nGenProcLimit, Params()); + CBitcoinAddress address(params[1].get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Error: Invalid address"); + + boost::shared_ptr<CReserveScript> coinbaseScript(new CReserveScript()); + coinbaseScript->reserveScript = GetScriptForDestination(address.Get()); - return NullUniValue; + return generateBlocks(coinbaseScript, nGenerate, nMaxTries, false); } UniValue getmininginfo(const UniValue& params, bool fHelp) @@ -239,8 +226,6 @@ UniValue getmininginfo(const UniValue& params, bool fHelp) " \"currentblocktx\": nnn, (numeric) The last block transaction\n" " \"difficulty\": xxx.xxxxx (numeric) The current difficulty\n" " \"errors\": \"...\" (string) Current errors\n" - " \"generate\": true|false (boolean) If the generation is on or off (see getgenerate or setgenerate calls)\n" - " \"genproclimit\": n (numeric) The processor limit for generation. -1 if no generation. (see getgenerate or setgenerate calls)\n" " \"pooledtx\": n (numeric) The size of the mem pool\n" " \"testnet\": true|false (boolean) If using testnet or not\n" " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n" @@ -259,12 +244,10 @@ UniValue getmininginfo(const UniValue& params, bool fHelp) obj.push_back(Pair("currentblocktx", (uint64_t)nLastBlockTx)); obj.push_back(Pair("difficulty", (double)GetDifficulty())); obj.push_back(Pair("errors", GetWarnings("statusbar"))); - obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", DEFAULT_GENERATE_THREADS))); obj.push_back(Pair("networkhashps", getnetworkhashps(params, false))); obj.push_back(Pair("pooledtx", (uint64_t)mempool.size())); obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC())); obj.push_back(Pair("chain", Params().NetworkIDString())); - obj.push_back(Pair("generate", getgenerate(params, false))); return obj; } @@ -798,3 +781,27 @@ UniValue estimatesmartpriority(const UniValue& params, bool fHelp) result.push_back(Pair("blocks", answerFound)); return result; } + +static const CRPCCommand commands[] = +{ // category name actor (function) okSafeMode + // --------------------- ------------------------ ----------------------- ---------- + { "mining", "getnetworkhashps", &getnetworkhashps, true }, + { "mining", "getmininginfo", &getmininginfo, true }, + { "mining", "prioritisetransaction", &prioritisetransaction, true }, + { "mining", "getblocktemplate", &getblocktemplate, true }, + { "mining", "submitblock", &submitblock, true }, + + { "generating", "generate", &generate, true }, + { "generating", "generatetoaddress", &generatetoaddress, true }, + + { "util", "estimatefee", &estimatefee, true }, + { "util", "estimatepriority", &estimatepriority, true }, + { "util", "estimatesmartfee", &estimatesmartfee, true }, + { "util", "estimatesmartpriority", &estimatesmartpriority, true }, +}; + +void RegisterMiningRPCCommands(CRPCTable &tableRPC) +{ + for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) + tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]); +} |