diff options
Diffstat (limited to 'src/rpcmining.cpp')
| -rw-r--r-- | src/rpcmining.cpp | 135 |
1 files changed, 65 insertions, 70 deletions
diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index d58d43857..b7d4ff58f 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -4,6 +4,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "amount.h" +#include "chain.h" #include "chainparams.h" #include "consensus/consensus.h" #include "consensus/validation.h" @@ -14,20 +15,18 @@ #include "net.h" #include "pow.h" #include "rpcserver.h" +#include "txmempool.h" #include "util.h" +#include "utilstrencodings.h" #include "validationinterface.h" -#ifdef ENABLE_WALLET -#include "wallet/wallet.h" -#endif #include <stdint.h> #include <boost/assign/list_of.hpp> +#include <boost/shared_ptr.hpp> -#include "json/json_spirit_utils.h" -#include "json/json_spirit_value.h" +#include "univalue/univalue.h" -using namespace json_spirit; using namespace std; /** @@ -35,7 +34,7 @@ using namespace std; * or from the last difficulty change if 'lookup' is nonpositive. * If 'height' is nonnegative, compute the estimate at the time when a given block was found. */ -Value GetNetworkHashPS(int lookup, int height) { +UniValue GetNetworkHashPS(int lookup, int height) { CBlockIndex *pb = chainActive.Tip(); if (height >= 0 && height < chainActive.Height()) @@ -72,7 +71,7 @@ Value GetNetworkHashPS(int lookup, int height) { return (int64_t)(workDiff.getdouble() / timeDiff); } -Value getnetworkhashps(const Array& params, bool fHelp) +UniValue getnetworkhashps(const UniValue& params, bool fHelp) { if (fHelp || params.size() > 2) throw runtime_error( @@ -94,8 +93,7 @@ Value getnetworkhashps(const Array& params, bool fHelp) return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1); } -#ifdef ENABLE_WALLET -Value getgenerate(const Array& params, bool fHelp) +UniValue getgenerate(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -114,7 +112,7 @@ Value getgenerate(const Array& params, bool fHelp) return GetBoolArg("-gen", false); } -Value generate(const Array& params, bool fHelp) +UniValue generate(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 1) throw runtime_error( @@ -129,8 +127,6 @@ Value generate(const Array& params, bool fHelp) + HelpExampleCli("generate", "11") ); - if (pwalletMain == NULL) - throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)"); if (!Params().MineBlocksOnDemand()) throw JSONRPCError(RPC_METHOD_NOT_FOUND, "This method can only be used on regtest"); @@ -138,7 +134,13 @@ Value generate(const Array& params, bool fHelp) int nHeightEnd = 0; int nHeight = 0; int nGenerate = params[0].get_int(); - CReserveKey reservekey(pwalletMain); + + boost::shared_ptr<CReserveScript> coinbaseScript; + GetMainSignals().ScriptForMining(coinbaseScript); + + //throw an error if no script was provided + if (!coinbaseScript->reserveScript.size()) + throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available (mining requires a wallet)"); { // Don't keep cs_main locked LOCK(cs_main); @@ -147,12 +149,12 @@ Value generate(const Array& params, bool fHelp) nHeightEnd = nHeightStart+nGenerate; } unsigned int nExtraNonce = 0; - Array blockHashes; + UniValue blockHashes(UniValue::VARR); while (nHeight < nHeightEnd) { - auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey)); + auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlock(coinbaseScript->reserveScript)); if (!pblocktemplate.get()) - throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet keypool empty"); + throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block"); CBlock *pblock = &pblocktemplate->block; { LOCK(cs_main); @@ -164,16 +166,18 @@ Value generate(const Array& params, bool fHelp) ++pblock->nNonce; } CValidationState state; - if (!ProcessNewBlock(state, NULL, pblock)) + if (!ProcessNewBlock(state, NULL, pblock, true, NULL)) throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted"); ++nHeight; blockHashes.push_back(pblock->GetHash().GetHex()); + + //mark script as important because it was used at least for one coinbase output + coinbaseScript->KeepScript(); } return blockHashes; } - -Value setgenerate(const Array& params, bool fHelp) +UniValue setgenerate(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -195,8 +199,6 @@ Value setgenerate(const Array& params, bool fHelp) + HelpExampleRpc("setgenerate", "true, 1") ); - if (pwalletMain == NULL) - throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)"); if (Params().MineBlocksOnDemand()) throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Use the generate method instead of setgenerate on this network"); @@ -214,14 +216,12 @@ Value setgenerate(const Array& params, bool fHelp) mapArgs["-gen"] = (fGenerate ? "1" : "0"); mapArgs ["-genproclimit"] = itostr(nGenProcLimit); - GenerateBitcoins(fGenerate, pwalletMain, nGenProcLimit); + GenerateBitcoins(fGenerate, nGenProcLimit, Params()); - return Value::null; + return NullUniValue; } -#endif - -Value getmininginfo(const Array& params, bool fHelp) +UniValue getmininginfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -248,7 +248,7 @@ Value getmininginfo(const Array& params, bool fHelp) LOCK(cs_main); - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("blocks", (int)chainActive.Height())); obj.push_back(Pair("currentblocksize", (uint64_t)nLastBlockSize)); obj.push_back(Pair("currentblocktx", (uint64_t)nLastBlockTx)); @@ -259,15 +259,13 @@ Value getmininginfo(const Array& params, bool fHelp) obj.push_back(Pair("pooledtx", (uint64_t)mempool.size())); obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC())); obj.push_back(Pair("chain", Params().NetworkIDString())); -#ifdef ENABLE_WALLET obj.push_back(Pair("generate", getgenerate(params, false))); -#endif return obj; } // NOTE: Unlike wallet RPC (which use BTC values), mining RPCs follow GBT (BIP 22) in using satoshi amounts -Value prioritisetransaction(const Array& params, bool fHelp) +UniValue prioritisetransaction(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 3) throw runtime_error( @@ -299,10 +297,10 @@ Value prioritisetransaction(const Array& params, bool fHelp) // NOTE: Assumes a conclusive result; if result is inconclusive, it must be handled by caller -static Value BIP22ValidationResult(const CValidationState& state) +static UniValue BIP22ValidationResult(const CValidationState& state) { if (state.IsValid()) - return Value::null; + return NullUniValue; std::string strRejectReason = state.GetRejectReason(); if (state.IsError()) @@ -317,7 +315,7 @@ static Value BIP22ValidationResult(const CValidationState& state) return "valid?"; } -Value getblocktemplate(const Array& params, bool fHelp) +UniValue getblocktemplate(const UniValue& params, bool fHelp) { if (fHelp || params.size() > 1) throw runtime_error( @@ -382,14 +380,14 @@ Value getblocktemplate(const Array& params, bool fHelp) LOCK(cs_main); std::string strMode = "template"; - Value lpval = Value::null; + UniValue lpval = NullUniValue; if (params.size() > 0) { - const Object& oparam = params[0].get_obj(); - const Value& modeval = find_value(oparam, "mode"); - if (modeval.type() == str_type) + const UniValue& oparam = params[0].get_obj(); + const UniValue& modeval = find_value(oparam, "mode"); + if (modeval.isStr()) strMode = modeval.get_str(); - else if (modeval.type() == null_type) + else if (modeval.isNull()) { /* Do nothing */ } @@ -399,8 +397,8 @@ Value getblocktemplate(const Array& params, bool fHelp) if (strMode == "proposal") { - const Value& dataval = find_value(oparam, "data"); - if (dataval.type() != str_type) + const UniValue& dataval = find_value(oparam, "data"); + if (!dataval.isStr()) throw JSONRPCError(RPC_TYPE_ERROR, "Missing data String key for proposal"); CBlock block; @@ -439,14 +437,14 @@ Value getblocktemplate(const Array& params, bool fHelp) static unsigned int nTransactionsUpdatedLast; - if (lpval.type() != null_type) + if (!lpval.isNull()) { // Wait to respond until either the best block changes, OR a minute has passed and there are more transactions uint256 hashWatchedChain; boost::system_time checktxtime; unsigned int nTransactionsUpdatedLastLP; - if (lpval.type() == str_type) + if (lpval.isStr()) { // Format: <hashBestChain><nTransactionsUpdatedLast> std::string lpstr = lpval.get_str(); @@ -520,26 +518,25 @@ Value getblocktemplate(const Array& params, bool fHelp) UpdateTime(pblock, Params().GetConsensus(), pindexPrev); pblock->nNonce = 0; - static const Array aCaps = boost::assign::list_of("proposal"); + UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal"); - Array transactions; + UniValue transactions(UniValue::VARR); map<uint256, int64_t> setTxIndex; int i = 0; - BOOST_FOREACH (CTransaction& tx, pblock->vtx) - { + BOOST_FOREACH (const CTransaction& tx, pblock->vtx) { uint256 txHash = tx.GetHash(); setTxIndex[txHash] = i++; if (tx.IsCoinBase()) continue; - Object entry; + UniValue entry(UniValue::VOBJ); entry.push_back(Pair("data", EncodeHexTx(tx))); entry.push_back(Pair("hash", txHash.GetHex())); - Array deps; + UniValue deps(UniValue::VARR); BOOST_FOREACH (const CTxIn &in, tx.vin) { if (setTxIndex.count(in.prevout.hash)) @@ -554,12 +551,12 @@ Value getblocktemplate(const Array& params, bool fHelp) transactions.push_back(entry); } - Object aux; + UniValue aux(UniValue::VOBJ); aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end()))); arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits); - static Array aMutable; + static UniValue aMutable(UniValue::VARR); if (aMutable.empty()) { aMutable.push_back("time"); @@ -567,7 +564,7 @@ Value getblocktemplate(const Array& params, bool fHelp) aMutable.push_back("prevblock"); } - Object result; + UniValue result(UniValue::VOBJ); result.push_back(Pair("capabilities", aCaps)); result.push_back(Pair("version", pblock->nVersion)); result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex())); @@ -606,7 +603,7 @@ protected: }; }; -Value submitblock(const Array& params, bool fHelp) +UniValue submitblock(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -650,7 +647,7 @@ Value submitblock(const Array& params, bool fHelp) CValidationState state; submitblock_StateCatcher sc(block.GetHash()); RegisterValidationInterface(&sc); - bool fAccepted = ProcessNewBlock(state, NULL, &block); + bool fAccepted = ProcessNewBlock(state, NULL, &block, true, NULL); UnregisterValidationInterface(&sc); if (fBlockPresent) { @@ -667,26 +664,25 @@ Value submitblock(const Array& params, bool fHelp) return BIP22ValidationResult(state); } -Value estimatefee(const Array& params, bool fHelp) +UniValue estimatefee(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( "estimatefee nblocks\n" - "\nEstimates the approximate fee per kilobyte\n" - "needed for a transaction to begin confirmation\n" - "within nblocks blocks.\n" + "\nEstimates the approximate fee per kilobyte needed for a transaction to begin\n" + "confirmation within nblocks blocks.\n" "\nArguments:\n" "1. nblocks (numeric)\n" "\nResult:\n" - "n : (numeric) estimated fee-per-kilobyte\n" + "n (numeric) estimated fee-per-kilobyte\n" "\n" - "-1.0 is returned if not enough transactions and\n" - "blocks have been observed to make an estimate.\n" + "A negative value is returned if not enough transactions and blocks\n" + "have been observed to make an estimate.\n" "\nExample:\n" + HelpExampleCli("estimatefee", "6") ); - RPCTypeCheck(params, boost::assign::list_of(int_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)); int nBlocks = params[0].get_int(); if (nBlocks < 1) @@ -699,26 +695,25 @@ Value estimatefee(const Array& params, bool fHelp) return ValueFromAmount(feeRate.GetFeePerK()); } -Value estimatepriority(const Array& params, bool fHelp) +UniValue estimatepriority(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( "estimatepriority nblocks\n" - "\nEstimates the approximate priority\n" - "a zero-fee transaction needs to begin confirmation\n" - "within nblocks blocks.\n" + "\nEstimates the approximate priority a zero-fee transaction needs to begin\n" + "confirmation within nblocks blocks.\n" "\nArguments:\n" "1. nblocks (numeric)\n" "\nResult:\n" - "n : (numeric) estimated priority\n" + "n (numeric) estimated priority\n" "\n" - "-1.0 is returned if not enough transactions and\n" - "blocks have been observed to make an estimate.\n" + "A negative value is returned if not enough transactions and blocks\n" + "have been observed to make an estimate.\n" "\nExample:\n" + HelpExampleCli("estimatepriority", "6") ); - RPCTypeCheck(params, boost::assign::list_of(int_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)); int nBlocks = params[0].get_int(); if (nBlocks < 1) |