diff --git a/src/Makefile.gtest.include b/src/Makefile.gtest.include index 3f076161f..a9e5e04dc 100644 --- a/src/Makefile.gtest.include +++ b/src/Makefile.gtest.include @@ -26,6 +26,7 @@ zcash_gtest_SOURCES += \ gtest/test_noteencryption.cpp \ gtest/test_merkletree.cpp \ gtest/test_metrics.cpp \ + gtest/test_miner.cpp \ gtest/test_pow.cpp \ gtest/test_random.cpp \ gtest/test_rpc.cpp \ diff --git a/src/gtest/test_miner.cpp b/src/gtest/test_miner.cpp new file mode 100644 index 000000000..c232af842 --- /dev/null +++ b/src/gtest/test_miner.cpp @@ -0,0 +1,103 @@ +#include +#include + +#include "chainparams.h" +#include "key.h" +#include "miner.h" +#include "util.h" +#ifdef ENABLE_WALLET +#include "wallet/wallet.h" +#endif + +#include + +using ::testing::Return; + +#ifdef ENABLE_WALLET +class MockReserveKey : public CReserveKey { +public: + MockReserveKey() : CReserveKey(nullptr) { } + + MOCK_METHOD1(GetReservedKey, bool(CPubKey &pubkey)); +}; +#endif + +TEST(Miner, GetMinerScriptPubKey) { + SelectParams(CBaseChainParams::MAIN); + + boost::optional scriptPubKey; +#ifdef ENABLE_WALLET + MockReserveKey reservekey; + EXPECT_CALL(reservekey, GetReservedKey(::testing::_)) + .WillRepeatedly(Return(false)); +#endif + + // No miner address set +#ifdef ENABLE_WALLET + scriptPubKey = GetMinerScriptPubKey(reservekey); +#else + scriptPubKey = GetMinerScriptPubKey(); +#endif + EXPECT_FALSE((bool) scriptPubKey); + + mapArgs["-mineraddress"] = "notAnAddress"; +#ifdef ENABLE_WALLET + scriptPubKey = GetMinerScriptPubKey(reservekey); +#else + scriptPubKey = GetMinerScriptPubKey(); +#endif + EXPECT_FALSE((bool) scriptPubKey); + + // Partial address + mapArgs["-mineraddress"] = "t1T8yaLVhNqxA5KJcmiqq"; +#ifdef ENABLE_WALLET + scriptPubKey = GetMinerScriptPubKey(reservekey); +#else + scriptPubKey = GetMinerScriptPubKey(); +#endif + EXPECT_FALSE((bool) scriptPubKey); + + // Typo in address + mapArgs["-mineraddress"] = "t1TByaLVhNqxA5KJcmiqqFN88e8DNp2PBfF"; +#ifdef ENABLE_WALLET + scriptPubKey = GetMinerScriptPubKey(reservekey); +#else + scriptPubKey = GetMinerScriptPubKey(); +#endif + EXPECT_FALSE((bool) scriptPubKey); + + // Set up expected scriptPubKey for t1T8yaLVhNqxA5KJcmiqqFN88e8DNp2PBfF + CKeyID keyID; + keyID.SetHex("eb88f1c65b39a823479ac9c7db2f4a865960a165"); + CScript expectedScriptPubKey = CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG; + + // Valid address + mapArgs["-mineraddress"] = "t1T8yaLVhNqxA5KJcmiqqFN88e8DNp2PBfF"; +#ifdef ENABLE_WALLET + scriptPubKey = GetMinerScriptPubKey(reservekey); +#else + scriptPubKey = GetMinerScriptPubKey(); +#endif + EXPECT_TRUE((bool) scriptPubKey); + EXPECT_EQ(expectedScriptPubKey, *scriptPubKey); + + // Valid address with leading whitespace + mapArgs["-mineraddress"] = " t1T8yaLVhNqxA5KJcmiqqFN88e8DNp2PBfF"; +#ifdef ENABLE_WALLET + scriptPubKey = GetMinerScriptPubKey(reservekey); +#else + scriptPubKey = GetMinerScriptPubKey(); +#endif + EXPECT_TRUE((bool) scriptPubKey); + EXPECT_EQ(expectedScriptPubKey, *scriptPubKey); + + // Valid address with trailing whitespace + mapArgs["-mineraddress"] = "t1T8yaLVhNqxA5KJcmiqqFN88e8DNp2PBfF "; +#ifdef ENABLE_WALLET + scriptPubKey = GetMinerScriptPubKey(reservekey); +#else + scriptPubKey = GetMinerScriptPubKey(); +#endif + EXPECT_TRUE((bool) scriptPubKey); + EXPECT_EQ(expectedScriptPubKey, *scriptPubKey); +} diff --git a/src/init.cpp b/src/init.cpp index 94b8ae527..0df20e242 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -11,6 +11,9 @@ #include "crypto/common.h" #include "addrman.h" #include "amount.h" +#ifdef ENABLE_MINING +#include "base58.h" +#endif #include "checkpoints.h" #include "compat/sanity.h" #include "consensus/validation.h" @@ -170,8 +173,12 @@ void Shutdown() #ifdef ENABLE_WALLET if (pwalletMain) pwalletMain->Flush(false); - #ifdef ENABLE_MINING +#endif +#ifdef ENABLE_MINING + #ifdef ENABLE_WALLET GenerateBitcoins(false, NULL, 0); + #else + GenerateBitcoins(false, 0); #endif #endif StopNode(); @@ -409,11 +416,6 @@ std::string HelpMessage(HelpMessageMode mode) debugCategories += ", qt"; strUsage += HelpMessageOpt("-debug=", strprintf(_("Output debugging information (default: %u, supplying is optional)"), 0) + ". " + _("If is not supplied or if = 1, output all debugging information.") + " " + _(" can be:") + " " + debugCategories + "."); -#ifdef ENABLE_WALLET - strUsage += HelpMessageOpt("-gen", strprintf(_("Generate coins (default: %u)"), 0)); - strUsage += HelpMessageOpt("-genproclimit=", strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), 1)); - strUsage += HelpMessageOpt("-equihashsolver=", _("Specify the Equihash solver to be used if enabled (default: \"default\")")); -#endif strUsage += HelpMessageOpt("-help-debug", _("Show all debugging options (usage: --help -help-debug)")); strUsage += HelpMessageOpt("-logips", strprintf(_("Include IP addresses in debug output (default: %u)"), 0)); strUsage += HelpMessageOpt("-logtimestamps", strprintf(_("Prepend debug output with timestamp (default: %u)"), 1)); @@ -444,6 +446,22 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-blockmaxsize=", strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE)); strUsage += HelpMessageOpt("-blockprioritysize=", strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE)); +#ifdef ENABLE_MINING + strUsage += HelpMessageGroup(_("Mining options:")); + strUsage += HelpMessageOpt("-gen", strprintf(_("Generate coins (default: %u)"), 0)); + strUsage += HelpMessageOpt("-genproclimit=", strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), 1)); + strUsage += HelpMessageOpt("-equihashsolver=", _("Specify the Equihash solver to be used if enabled (default: \"default\")")); + strUsage += HelpMessageOpt("-mineraddress=", _("Send mined coins to a specific single address")); + strUsage += HelpMessageOpt("-minetolocalwallet", strprintf( + _("Require that mined blocks use a coinbase address in the local wallet (default: %u)"), + #ifdef ENABLE_WALLET + 1 + #else + 0 + #endif + )); +#endif + strUsage += HelpMessageGroup(_("RPC server options:")); strUsage += HelpMessageOpt("-server", _("Accept command line and JSON-RPC commands")); strUsage += HelpMessageOpt("-rest", strprintf(_("Accept public REST requests (default: %u)"), 0)); @@ -952,6 +970,17 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) fAlerts = GetBoolArg("-alerts", DEFAULT_ALERTS); +#ifdef ENABLE_MINING + if (mapArgs.count("-mineraddress")) { + CBitcoinAddress addr; + if (!addr.SetString(mapArgs["-mineraddress"])) { + return InitError(strprintf( + _("Invalid address for -mineraddress=: '%s' (must be a transparent address)"), + mapArgs["-mineraddress"])); + } + } +#endif + // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log // Initialize libsodium @@ -1477,6 +1506,35 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) LogPrintf("No wallet support compiled in!\n"); #endif // !ENABLE_WALLET +#ifdef ENABLE_MINING + #ifndef ENABLE_WALLET + auto mineToLocalWallet = GetBoolArg("-minetolocalwallet", false); + if (mineToLocalWallet) { + return InitError(_("Zcash was not built with wallet support. Set -minetolocalwallet=0 to use -mineraddress, or rebuild Zcash with wallet support.")); + } + if (!mapArgs.count("-mineraddress")) { + return InitError(_("Zcash was not built with wallet support. Set -mineraddress, or rebuild Zcash with wallet support.")); + } + #endif // !ENABLE_WALLET + + if (mapArgs.count("-mineraddress")) { + #ifdef ENABLE_WALLET + auto mineToLocalWallet = GetBoolArg("-minetolocalwallet", true); + bool minerAddressInLocalWallet = false; + if (pwalletMain) { + // Address has alreday been validated + CBitcoinAddress addr(mapArgs["-mineraddress"]); + CKeyID keyID; + addr.GetKeyID(keyID); + minerAddressInLocalWallet = pwalletMain->HaveKey(keyID); + } + if (mineToLocalWallet && !minerAddressInLocalWallet) { + return InitError(_("-mineraddress is not in the local wallet. Either use a local address, or set -minetolocalwallet=0")); + } + #endif // ENABLE_WALLET + } +#endif // ENABLE_MINING + // ********************************************************* Step 9: data directory maintenance // if pruning, unset the service bit and perform the initial blockstore prune @@ -1539,10 +1597,14 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) boost::ref(cs_main), boost::cref(pindexBestHeader), nPowTargetSpacing); scheduler.scheduleEvery(f, nPowTargetSpacing); -#if defined(ENABLE_WALLET) && defined(ENABLE_MINING) +#ifdef ENABLE_MINING // Generate coins in the background - if (pwalletMain) + #ifdef ENABLE_WALLET + if (pwalletMain || !GetArg("-mineraddress", "").empty()) GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain, GetArg("-genproclimit", 1)); + #else + GenerateBitcoins(GetBoolArg("-gen", false), GetArg("-genproclimit", 1)); + #endif #endif // ********************************************************* Step 11: finished diff --git a/src/miner.cpp b/src/miner.cpp index 0306871a4..5e2811504 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -4,14 +4,18 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "miner.h" -#if defined(ENABLE_WALLET) && defined(ENABLE_MINING) +#ifdef ENABLE_MINING #include "pow/tromp/equi_miner.h" #endif #include "amount.h" +#include "base58.h" #include "chainparams.h" #include "consensus/consensus.h" #include "consensus/validation.h" +#ifdef ENABLE_MINING +#include "crypto/equihash.h" +#endif #include "hash.h" #include "main.h" #include "metrics.h" @@ -20,20 +24,20 @@ #include "primitives/transaction.h" #include "random.h" #include "timedata.h" +#include "ui_interface.h" #include "util.h" #include "utilmoneystr.h" #ifdef ENABLE_WALLET - #ifdef ENABLE_MINING -#include "crypto/equihash.h" - #endif #include "wallet/wallet.h" -#include #endif #include "sodium.h" #include #include +#ifdef ENABLE_MINING +#include +#endif #include using namespace std; @@ -383,6 +387,55 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) return pblocktemplate.release(); } +#ifdef ENABLE_WALLET +boost::optional GetMinerScriptPubKey(CReserveKey& reservekey) +#else +boost::optional GetMinerScriptPubKey() +#endif +{ + CKeyID keyID; + CBitcoinAddress addr; + if (addr.SetString(GetArg("-mineraddress", ""))) { + addr.GetKeyID(keyID); + } else { +#ifdef ENABLE_WALLET + CPubKey pubkey; + if (!reservekey.GetReservedKey(pubkey)) { + return boost::optional(); + } + keyID = pubkey.GetID(); +#else + return boost::optional(); +#endif + } + + CScript scriptPubKey = CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG; + return scriptPubKey; +} + +#ifdef ENABLE_WALLET +CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey) +{ + boost::optional scriptPubKey = GetMinerScriptPubKey(reservekey); +#else +CBlockTemplate* CreateNewBlockWithKey() +{ + boost::optional scriptPubKey = GetMinerScriptPubKey(); +#endif + + if (!scriptPubKey) { + return NULL; + } + return CreateNewBlock(*scriptPubKey); +} + +////////////////////////////////////////////////////////////////////////////// +// +// Internal miner +// + +#ifdef ENABLE_MINING + void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce) { // Update nExtraNonce @@ -403,23 +456,10 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& } #ifdef ENABLE_WALLET -////////////////////////////////////////////////////////////////////////////// -// -// Internal miner -// - -CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey) -{ - CPubKey pubkey; - if (!reservekey.GetReservedKey(pubkey)) - return NULL; - - CScript scriptPubKey = CScript() << ToByteVector(pubkey) << OP_CHECKSIG; - return CreateNewBlock(scriptPubKey); -} - -#ifdef ENABLE_MINING static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) +#else +static bool ProcessBlockFound(CBlock* pblock) +#endif // ENABLE_WALLET { LogPrintf("%s\n", pblock->ToString()); LogPrintf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue)); @@ -431,14 +471,18 @@ static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& rese return error("ZcashMiner: generated block is stale"); } - // Remove key from key pool - reservekey.KeepKey(); +#ifdef ENABLE_WALLET + if (GetArg("-mineraddress", "").empty()) { + // Remove key from key pool + reservekey.KeepKey(); + } // Track how many getdata requests this block gets { LOCK(wallet.cs_wallet); wallet.mapRequestCount[pblock->GetHash()] = 0; } +#endif // Process this block the same as if we had received it from another node CValidationState state; @@ -450,15 +494,23 @@ static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& rese return true; } +#ifdef ENABLE_WALLET void static BitcoinMiner(CWallet *pwallet) +#else +void static BitcoinMiner() +#endif { LogPrintf("ZcashMiner started\n"); SetThreadPriority(THREAD_PRIORITY_LOWEST); RenameThread("zcash-miner"); const CChainParams& chainparams = Params(); - // Each thread has its own key and counter +#ifdef ENABLE_WALLET + // Each thread has its own key CReserveKey reservekey(pwallet); +#endif + + // Each thread has its own counter unsigned int nExtraNonce = 0; unsigned int n = chainparams.EquihashN(); @@ -500,10 +552,19 @@ void static BitcoinMiner(CWallet *pwallet) unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); CBlockIndex* pindexPrev = chainActive.Tip(); +#ifdef ENABLE_WALLET unique_ptr pblocktemplate(CreateNewBlockWithKey(reservekey)); +#else + unique_ptr pblocktemplate(CreateNewBlockWithKey()); +#endif if (!pblocktemplate.get()) { - LogPrintf("Error in ZcashMiner: Keypool ran out, please call keypoolrefill before restarting the mining thread\n"); + if (GetArg("-mineraddress", "").empty()) { + LogPrintf("Error in ZcashMiner: Keypool ran out, please call keypoolrefill before restarting the mining thread\n"); + } else { + // Should never reach here, because -mineraddress validity is checked in init.cpp + LogPrintf("Error in ZcashMiner: Invalid -mineraddress\n"); + } return; } CBlock *pblock = &pblocktemplate->block; @@ -543,7 +604,11 @@ void static BitcoinMiner(CWallet *pwallet) solver, pblock->nNonce.ToString()); std::function)> validBlock = +#ifdef ENABLE_WALLET [&pblock, &hashTarget, &pwallet, &reservekey, &m_cs, &cancelSolver, &chainparams] +#else + [&pblock, &hashTarget, &m_cs, &cancelSolver, &chainparams] +#endif (std::vector soln) { // Write the solution to the hash and compute the result. LogPrint("pow", "- Checking solution against target\n"); @@ -558,7 +623,11 @@ void static BitcoinMiner(CWallet *pwallet) SetThreadPriority(THREAD_PRIORITY_NORMAL); LogPrintf("ZcashMiner:\n"); LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", pblock->GetHash().GetHex(), hashTarget.GetHex()); +#ifdef ENABLE_WALLET if (ProcessBlockFound(pblock, *pwallet, reservekey)) { +#else + if (ProcessBlockFound(pblock)) { +#endif // Ignore chain updates caused by us std::lock_guard lock{m_cs}; cancelSolver = false; @@ -665,7 +734,11 @@ void static BitcoinMiner(CWallet *pwallet) c.disconnect(); } +#ifdef ENABLE_WALLET void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads) +#else +void GenerateBitcoins(bool fGenerate, int nThreads) +#endif { static boost::thread_group* minerThreads = NULL; @@ -688,9 +761,13 @@ void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads) return; minerThreads = new boost::thread_group(); - for (int i = 0; i < nThreads; i++) + for (int i = 0; i < nThreads; i++) { +#ifdef ENABLE_WALLET minerThreads->create_thread(boost::bind(&BitcoinMiner, pwallet)); +#else + minerThreads->create_thread(&BitcoinMiner); +#endif + } } #endif // ENABLE_MINING -#endif // ENABLE_WALLET diff --git a/src/miner.h b/src/miner.h index 8c8402771..bf1a088f0 100644 --- a/src/miner.h +++ b/src/miner.h @@ -8,12 +8,15 @@ #include "primitives/block.h" +#include #include class CBlockIndex; -class CReserveKey; class CScript; +#ifdef ENABLE_WALLET +class CReserveKey; class CWallet; +#endif namespace Consensus { struct Params; }; struct CBlockTemplate @@ -23,15 +26,27 @@ struct CBlockTemplate std::vector vTxSigOps; }; -#ifdef ENABLE_MINING -/** Run the miner threads */ -void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads); -#endif /** Generate a new block, without valid proof-of-work */ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn); +#ifdef ENABLE_WALLET +boost::optional GetMinerScriptPubKey(CReserveKey& reservekey); CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey); +#else +boost::optional GetMinerScriptPubKey(); +CBlockTemplate* CreateNewBlockWithKey(); +#endif + +#ifdef ENABLE_MINING /** Modify the extranonce in a block */ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce); +/** Run the miner threads */ + #ifdef ENABLE_WALLET +void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads); + #else +void GenerateBitcoins(bool fGenerate, int nThreads); + #endif +#endif + void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev); #endif // BITCOIN_MINER_H diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 1fcca5bca..c500db398 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -8,7 +8,9 @@ #include "consensus/consensus.h" #include "consensus/validation.h" #include "core_io.h" +#ifdef ENABLE_MINING #include "crypto/equihash.h" +#endif #include "init.h" #include "main.h" #include "metrics.h" @@ -137,7 +139,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); } -#if defined(ENABLE_WALLET) && defined(ENABLE_MINING) +#ifdef ENABLE_MINING Value getgenerate(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) @@ -173,8 +175,15 @@ Value generate(const Array& params, bool fHelp) + HelpExampleCli("generate", "11") ); - if (pwalletMain == NULL) - throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)"); + if (GetArg("-mineraddress", "").empty()) { +#ifdef ENABLE_WALLET + if (!pwalletMain) { + throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Wallet disabled and -mineraddress not set"); + } +#else + throw JSONRPCError(RPC_METHOD_NOT_FOUND, "zcashd compiled without wallet and -mineraddress not set"); +#endif + } if (!Params().MineBlocksOnDemand()) throw JSONRPCError(RPC_METHOD_NOT_FOUND, "This method can only be used on regtest"); @@ -182,7 +191,9 @@ Value generate(const Array& params, bool fHelp) int nHeightEnd = 0; int nHeight = 0; int nGenerate = params[0].get_int(); +#ifdef ENABLE_WALLET CReserveKey reservekey(pwalletMain); +#endif { // Don't keep cs_main locked LOCK(cs_main); @@ -196,7 +207,11 @@ Value generate(const Array& params, bool fHelp) unsigned int k = Params().EquihashK(); while (nHeight < nHeightEnd) { +#ifdef ENABLE_WALLET unique_ptr pblocktemplate(CreateNewBlockWithKey(reservekey)); +#else + unique_ptr pblocktemplate(CreateNewBlockWithKey()); +#endif if (!pblocktemplate.get()) throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet keypool empty"); CBlock *pblock = &pblocktemplate->block; @@ -275,8 +290,15 @@ 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 (GetArg("-mineraddress", "").empty()) { +#ifdef ENABLE_WALLET + if (!pwalletMain) { + throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Wallet disabled and -mineraddress not set"); + } +#else + throw JSONRPCError(RPC_METHOD_NOT_FOUND, "zcashd compiled without wallet and -mineraddress not set"); +#endif + } if (Params().MineBlocksOnDemand()) throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Use the generate method instead of setgenerate on this network"); @@ -294,7 +316,11 @@ Value setgenerate(const Array& params, bool fHelp) mapArgs["-gen"] = (fGenerate ? "1" : "0"); mapArgs ["-genproclimit"] = itostr(nGenProcLimit); +#ifdef ENABLE_WALLET GenerateBitcoins(fGenerate, pwalletMain, nGenProcLimit); +#else + GenerateBitcoins(fGenerate, nGenProcLimit); +#endif return Value::null; } @@ -343,7 +369,7 @@ 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())); -#if defined(ENABLE_WALLET) && defined(ENABLE_MINING) +#ifdef ENABLE_MINING obj.push_back(Pair("generate", getgenerate(params, false))); #endif return obj; @@ -401,7 +427,6 @@ static Value BIP22ValidationResult(const CValidationState& state) return "valid?"; } -#ifdef ENABLE_WALLET Value getblocktemplate(const Array& params, bool fHelp) { if (fHelp || params.size() > 1) @@ -466,10 +491,15 @@ Value getblocktemplate(const Array& params, bool fHelp) LOCK(cs_main); + // Wallet or miner address is required because we support coinbasetxn + if (GetArg("-mineraddress", "").empty()) { #ifdef ENABLE_WALLET - // Wallet is required because we support coinbasetxn - if (pwalletMain == NULL) { - throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (wallet disabled)"); + if (!pwalletMain) { + throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Wallet disabled and -mineraddress not set"); + } +#else + throw JSONRPCError(RPC_METHOD_NOT_FOUND, "zcashd compiled without wallet and -mineraddress not set"); +#endif } std::string strMode = "template"; @@ -599,8 +629,12 @@ Value getblocktemplate(const Array& params, bool fHelp) delete pblocktemplate; pblocktemplate = NULL; } +#ifdef ENABLE_WALLET CReserveKey reservekey(pwalletMain); pblocktemplate = CreateNewBlockWithKey(reservekey); +#else + pblocktemplate = CreateNewBlockWithKey(); +#endif if (!pblocktemplate) throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); @@ -695,12 +729,7 @@ Value getblocktemplate(const Array& params, bool fHelp) result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1))); return result; -#else // ENABLE_WALLET - // Wallet is required because we support coinbasetxn - throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (wallet support not built)"); -#endif // !ENABLE_WALLET } -#endif class submitblock_StateCatcher : public CValidationInterface { diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 658ccf8d4..4100a7f7c 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -313,7 +313,7 @@ static const CRPCCommand vRPCCommands[] = { "mining", "submitblock", &submitblock, true }, { "mining", "getblocksubsidy", &getblocksubsidy, true }, -#if defined(ENABLE_WALLET) && defined(ENABLE_MINING) +#ifdef ENABLE_MINING /* Coin generation */ { "generating", "getgenerate", &getgenerate, true }, { "generating", "setgenerate", &setgenerate, true }, diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 3d721fc40..222c8cea9 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1059,7 +1059,7 @@ public: } void ReturnKey(); - bool GetReservedKey(CPubKey &pubkey); + virtual bool GetReservedKey(CPubKey &pubkey); void KeepKey(); };