@@ -26,6 +26,7 @@ zcash_gtest_SOURCES += \
|
|||||||
gtest/test_noteencryption.cpp \
|
gtest/test_noteencryption.cpp \
|
||||||
gtest/test_merkletree.cpp \
|
gtest/test_merkletree.cpp \
|
||||||
gtest/test_metrics.cpp \
|
gtest/test_metrics.cpp \
|
||||||
|
gtest/test_miner.cpp \
|
||||||
gtest/test_pow.cpp \
|
gtest/test_pow.cpp \
|
||||||
gtest/test_random.cpp \
|
gtest/test_random.cpp \
|
||||||
gtest/test_rpc.cpp \
|
gtest/test_rpc.cpp \
|
||||||
|
|||||||
103
src/gtest/test_miner.cpp
Normal file
103
src/gtest/test_miner.cpp
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
#include <gmock/gmock.h>
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include "chainparams.h"
|
||||||
|
#include "key.h"
|
||||||
|
#include "miner.h"
|
||||||
|
#include "util.h"
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
|
#include "wallet/wallet.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
|
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<CScript> 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);
|
||||||
|
}
|
||||||
28
src/init.cpp
28
src/init.cpp
@@ -11,6 +11,9 @@
|
|||||||
#include "crypto/common.h"
|
#include "crypto/common.h"
|
||||||
#include "addrman.h"
|
#include "addrman.h"
|
||||||
#include "amount.h"
|
#include "amount.h"
|
||||||
|
#ifdef ENABLE_MINING
|
||||||
|
#include "base58.h"
|
||||||
|
#endif
|
||||||
#include "checkpoints.h"
|
#include "checkpoints.h"
|
||||||
#include "compat/sanity.h"
|
#include "compat/sanity.h"
|
||||||
#include "consensus/validation.h"
|
#include "consensus/validation.h"
|
||||||
@@ -163,8 +166,12 @@ void Shutdown()
|
|||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
if (pwalletMain)
|
if (pwalletMain)
|
||||||
pwalletMain->Flush(false);
|
pwalletMain->Flush(false);
|
||||||
#ifdef ENABLE_MINING
|
#endif
|
||||||
|
#ifdef ENABLE_MINING
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
GenerateBitcoins(false, NULL, 0);
|
GenerateBitcoins(false, NULL, 0);
|
||||||
|
#else
|
||||||
|
GenerateBitcoins(false, 0);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
StopNode();
|
StopNode();
|
||||||
@@ -919,6 +926,17 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||||||
|
|
||||||
fAlerts = GetBoolArg("-alerts", DEFAULT_ALERTS);
|
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=<addr>: '%s' (must be a transparent address)"),
|
||||||
|
mapArgs["-mineraddress"]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log
|
// ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log
|
||||||
|
|
||||||
// Initialize libsodium
|
// Initialize libsodium
|
||||||
@@ -1502,10 +1520,14 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||||||
boost::ref(cs_main), boost::cref(pindexBestHeader), nPowTargetSpacing);
|
boost::ref(cs_main), boost::cref(pindexBestHeader), nPowTargetSpacing);
|
||||||
scheduler.scheduleEvery(f, nPowTargetSpacing);
|
scheduler.scheduleEvery(f, nPowTargetSpacing);
|
||||||
|
|
||||||
#if defined(ENABLE_WALLET) && defined(ENABLE_MINING)
|
#ifdef ENABLE_MINING
|
||||||
// Generate coins in the background
|
// Generate coins in the background
|
||||||
if (pwalletMain)
|
#ifdef ENABLE_WALLET
|
||||||
|
if (pwalletMain || !GetArg("-mineraddress", "").empty())
|
||||||
GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain, GetArg("-genproclimit", 1));
|
GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain, GetArg("-genproclimit", 1));
|
||||||
|
#else
|
||||||
|
GenerateBitcoins(GetBoolArg("-gen", false), GetArg("-genproclimit", 1));
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ********************************************************* Step 11: finished
|
// ********************************************************* Step 11: finished
|
||||||
|
|||||||
110
src/miner.cpp
110
src/miner.cpp
@@ -4,14 +4,18 @@
|
|||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#include "miner.h"
|
#include "miner.h"
|
||||||
#if defined(ENABLE_WALLET) && defined(ENABLE_MINING)
|
#ifdef ENABLE_MINING
|
||||||
#include "pow/tromp/equi_miner.h"
|
#include "pow/tromp/equi_miner.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "amount.h"
|
#include "amount.h"
|
||||||
|
#include "base58.h"
|
||||||
#include "chainparams.h"
|
#include "chainparams.h"
|
||||||
#include "consensus/consensus.h"
|
#include "consensus/consensus.h"
|
||||||
#include "consensus/validation.h"
|
#include "consensus/validation.h"
|
||||||
|
#ifdef ENABLE_MINING
|
||||||
|
#include "crypto/equihash.h"
|
||||||
|
#endif
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "metrics.h"
|
#include "metrics.h"
|
||||||
@@ -20,20 +24,20 @@
|
|||||||
#include "primitives/transaction.h"
|
#include "primitives/transaction.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
#include "timedata.h"
|
#include "timedata.h"
|
||||||
|
#include "ui_interface.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "utilmoneystr.h"
|
#include "utilmoneystr.h"
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
#ifdef ENABLE_MINING
|
|
||||||
#include "crypto/equihash.h"
|
|
||||||
#endif
|
|
||||||
#include "wallet/wallet.h"
|
#include "wallet/wallet.h"
|
||||||
#include <functional>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "sodium.h"
|
#include "sodium.h"
|
||||||
|
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
#include <boost/tuple/tuple.hpp>
|
#include <boost/tuple/tuple.hpp>
|
||||||
|
#ifdef ENABLE_MINING
|
||||||
|
#include <functional>
|
||||||
|
#endif
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@@ -402,24 +406,59 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int&
|
|||||||
pblock->hashMerkleRoot = pblock->BuildMerkleTree();
|
pblock->hashMerkleRoot = pblock->BuildMerkleTree();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_WALLET
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Internal miner
|
// Internal miner
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
|
boost::optional<CScript> GetMinerScriptPubKey(CReserveKey& reservekey)
|
||||||
|
#else
|
||||||
|
boost::optional<CScript> 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<CScript>();
|
||||||
|
}
|
||||||
|
keyID = pubkey.GetID();
|
||||||
|
#else
|
||||||
|
return boost::optional<CScript>();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CScript scriptPubKey = CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG;
|
||||||
|
return scriptPubKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey)
|
CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey)
|
||||||
{
|
{
|
||||||
CPubKey pubkey;
|
boost::optional<CScript> scriptPubKey = GetMinerScriptPubKey(reservekey);
|
||||||
if (!reservekey.GetReservedKey(pubkey))
|
#else
|
||||||
return NULL;
|
CBlockTemplate* CreateNewBlockWithKey()
|
||||||
|
{
|
||||||
|
boost::optional<CScript> scriptPubKey = GetMinerScriptPubKey();
|
||||||
|
#endif
|
||||||
|
|
||||||
CScript scriptPubKey = CScript() << ToByteVector(pubkey) << OP_CHECKSIG;
|
if (!scriptPubKey) {
|
||||||
return CreateNewBlock(scriptPubKey);
|
return NULL;
|
||||||
|
}
|
||||||
|
return CreateNewBlock(*scriptPubKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_MINING
|
#ifdef ENABLE_MINING
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
|
static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
|
||||||
|
#else
|
||||||
|
static bool ProcessBlockFound(CBlock* pblock)
|
||||||
|
#endif // ENABLE_WALLET
|
||||||
{
|
{
|
||||||
LogPrintf("%s\n", pblock->ToString());
|
LogPrintf("%s\n", pblock->ToString());
|
||||||
LogPrintf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue));
|
LogPrintf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue));
|
||||||
@@ -431,14 +470,18 @@ static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& rese
|
|||||||
return error("ZcashMiner: generated block is stale");
|
return error("ZcashMiner: generated block is stale");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove key from key pool
|
#ifdef ENABLE_WALLET
|
||||||
reservekey.KeepKey();
|
if (GetArg("-mineraddress", "").empty()) {
|
||||||
|
// Remove key from key pool
|
||||||
|
reservekey.KeepKey();
|
||||||
|
}
|
||||||
|
|
||||||
// Track how many getdata requests this block gets
|
// Track how many getdata requests this block gets
|
||||||
{
|
{
|
||||||
LOCK(wallet.cs_wallet);
|
LOCK(wallet.cs_wallet);
|
||||||
wallet.mapRequestCount[pblock->GetHash()] = 0;
|
wallet.mapRequestCount[pblock->GetHash()] = 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Process this block the same as if we had received it from another node
|
// Process this block the same as if we had received it from another node
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
@@ -450,15 +493,23 @@ static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& rese
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
void static BitcoinMiner(CWallet *pwallet)
|
void static BitcoinMiner(CWallet *pwallet)
|
||||||
|
#else
|
||||||
|
void static BitcoinMiner()
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
LogPrintf("ZcashMiner started\n");
|
LogPrintf("ZcashMiner started\n");
|
||||||
SetThreadPriority(THREAD_PRIORITY_LOWEST);
|
SetThreadPriority(THREAD_PRIORITY_LOWEST);
|
||||||
RenameThread("zcash-miner");
|
RenameThread("zcash-miner");
|
||||||
const CChainParams& chainparams = Params();
|
const CChainParams& chainparams = Params();
|
||||||
|
|
||||||
// Each thread has its own key and counter
|
#ifdef ENABLE_WALLET
|
||||||
|
// Each thread has its own key
|
||||||
CReserveKey reservekey(pwallet);
|
CReserveKey reservekey(pwallet);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Each thread has its own counter
|
||||||
unsigned int nExtraNonce = 0;
|
unsigned int nExtraNonce = 0;
|
||||||
|
|
||||||
unsigned int n = chainparams.EquihashN();
|
unsigned int n = chainparams.EquihashN();
|
||||||
@@ -500,10 +551,19 @@ void static BitcoinMiner(CWallet *pwallet)
|
|||||||
unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
|
unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
|
||||||
CBlockIndex* pindexPrev = chainActive.Tip();
|
CBlockIndex* pindexPrev = chainActive.Tip();
|
||||||
|
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
unique_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey));
|
unique_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey));
|
||||||
|
#else
|
||||||
|
unique_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey());
|
||||||
|
#endif
|
||||||
if (!pblocktemplate.get())
|
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;
|
return;
|
||||||
}
|
}
|
||||||
CBlock *pblock = &pblocktemplate->block;
|
CBlock *pblock = &pblocktemplate->block;
|
||||||
@@ -543,7 +603,11 @@ void static BitcoinMiner(CWallet *pwallet)
|
|||||||
solver, pblock->nNonce.ToString());
|
solver, pblock->nNonce.ToString());
|
||||||
|
|
||||||
std::function<bool(std::vector<unsigned char>)> validBlock =
|
std::function<bool(std::vector<unsigned char>)> validBlock =
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
[&pblock, &hashTarget, &pwallet, &reservekey, &m_cs, &cancelSolver, &chainparams]
|
[&pblock, &hashTarget, &pwallet, &reservekey, &m_cs, &cancelSolver, &chainparams]
|
||||||
|
#else
|
||||||
|
[&pblock, &hashTarget, &m_cs, &cancelSolver, &chainparams]
|
||||||
|
#endif
|
||||||
(std::vector<unsigned char> soln) {
|
(std::vector<unsigned char> soln) {
|
||||||
// Write the solution to the hash and compute the result.
|
// Write the solution to the hash and compute the result.
|
||||||
LogPrint("pow", "- Checking solution against target\n");
|
LogPrint("pow", "- Checking solution against target\n");
|
||||||
@@ -558,7 +622,11 @@ void static BitcoinMiner(CWallet *pwallet)
|
|||||||
SetThreadPriority(THREAD_PRIORITY_NORMAL);
|
SetThreadPriority(THREAD_PRIORITY_NORMAL);
|
||||||
LogPrintf("ZcashMiner:\n");
|
LogPrintf("ZcashMiner:\n");
|
||||||
LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", pblock->GetHash().GetHex(), hashTarget.GetHex());
|
LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", pblock->GetHash().GetHex(), hashTarget.GetHex());
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
if (ProcessBlockFound(pblock, *pwallet, reservekey)) {
|
if (ProcessBlockFound(pblock, *pwallet, reservekey)) {
|
||||||
|
#else
|
||||||
|
if (ProcessBlockFound(pblock)) {
|
||||||
|
#endif
|
||||||
// Ignore chain updates caused by us
|
// Ignore chain updates caused by us
|
||||||
std::lock_guard<std::mutex> lock{m_cs};
|
std::lock_guard<std::mutex> lock{m_cs};
|
||||||
cancelSolver = false;
|
cancelSolver = false;
|
||||||
@@ -665,7 +733,11 @@ void static BitcoinMiner(CWallet *pwallet)
|
|||||||
c.disconnect();
|
c.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads)
|
void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads)
|
||||||
|
#else
|
||||||
|
void GenerateBitcoins(bool fGenerate, int nThreads)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
static boost::thread_group* minerThreads = NULL;
|
static boost::thread_group* minerThreads = NULL;
|
||||||
|
|
||||||
@@ -688,9 +760,13 @@ void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
minerThreads = new boost::thread_group();
|
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));
|
minerThreads->create_thread(boost::bind(&BitcoinMiner, pwallet));
|
||||||
|
#else
|
||||||
|
minerThreads->create_thread(&BitcoinMiner);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ENABLE_MINING
|
#endif // ENABLE_MINING
|
||||||
#endif // ENABLE_WALLET
|
|
||||||
|
|||||||
15
src/miner.h
15
src/miner.h
@@ -8,12 +8,15 @@
|
|||||||
|
|
||||||
#include "primitives/block.h"
|
#include "primitives/block.h"
|
||||||
|
|
||||||
|
#include <boost/optional.hpp>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
class CBlockIndex;
|
class CBlockIndex;
|
||||||
class CReserveKey;
|
|
||||||
class CScript;
|
class CScript;
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
|
class CReserveKey;
|
||||||
class CWallet;
|
class CWallet;
|
||||||
|
#endif
|
||||||
namespace Consensus { struct Params; };
|
namespace Consensus { struct Params; };
|
||||||
|
|
||||||
struct CBlockTemplate
|
struct CBlockTemplate
|
||||||
@@ -25,11 +28,21 @@ struct CBlockTemplate
|
|||||||
|
|
||||||
#ifdef ENABLE_MINING
|
#ifdef ENABLE_MINING
|
||||||
/** Run the miner threads */
|
/** Run the miner threads */
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads);
|
void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads);
|
||||||
|
#else
|
||||||
|
void GenerateBitcoins(bool fGenerate, int nThreads);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
/** Generate a new block, without valid proof-of-work */
|
/** Generate a new block, without valid proof-of-work */
|
||||||
CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn);
|
CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn);
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
|
boost::optional<CScript> GetMinerScriptPubKey(CReserveKey& reservekey);
|
||||||
CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey);
|
CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey);
|
||||||
|
#else
|
||||||
|
boost::optional<CScript> GetMinerScriptPubKey();
|
||||||
|
CBlockTemplate* CreateNewBlockWithKey();
|
||||||
|
#endif
|
||||||
/** Modify the extranonce in a block */
|
/** Modify the extranonce in a block */
|
||||||
void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
|
void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
|
||||||
void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev);
|
void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev);
|
||||||
|
|||||||
@@ -8,7 +8,9 @@
|
|||||||
#include "consensus/consensus.h"
|
#include "consensus/consensus.h"
|
||||||
#include "consensus/validation.h"
|
#include "consensus/validation.h"
|
||||||
#include "core_io.h"
|
#include "core_io.h"
|
||||||
|
#ifdef ENABLE_MINING
|
||||||
#include "crypto/equihash.h"
|
#include "crypto/equihash.h"
|
||||||
|
#endif
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "metrics.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);
|
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)
|
Value getgenerate(const Array& params, bool fHelp)
|
||||||
{
|
{
|
||||||
if (fHelp || params.size() != 0)
|
if (fHelp || params.size() != 0)
|
||||||
@@ -173,8 +175,15 @@ Value generate(const Array& params, bool fHelp)
|
|||||||
+ HelpExampleCli("generate", "11")
|
+ HelpExampleCli("generate", "11")
|
||||||
);
|
);
|
||||||
|
|
||||||
if (pwalletMain == NULL)
|
if (GetArg("-mineraddress", "").empty()) {
|
||||||
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
|
#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())
|
if (!Params().MineBlocksOnDemand())
|
||||||
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "This method can only be used on regtest");
|
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 nHeightEnd = 0;
|
||||||
int nHeight = 0;
|
int nHeight = 0;
|
||||||
int nGenerate = params[0].get_int();
|
int nGenerate = params[0].get_int();
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
CReserveKey reservekey(pwalletMain);
|
CReserveKey reservekey(pwalletMain);
|
||||||
|
#endif
|
||||||
|
|
||||||
{ // Don't keep cs_main locked
|
{ // Don't keep cs_main locked
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
@@ -196,7 +207,11 @@ Value generate(const Array& params, bool fHelp)
|
|||||||
unsigned int k = Params().EquihashK();
|
unsigned int k = Params().EquihashK();
|
||||||
while (nHeight < nHeightEnd)
|
while (nHeight < nHeightEnd)
|
||||||
{
|
{
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
unique_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey));
|
unique_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey));
|
||||||
|
#else
|
||||||
|
unique_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey());
|
||||||
|
#endif
|
||||||
if (!pblocktemplate.get())
|
if (!pblocktemplate.get())
|
||||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet keypool empty");
|
throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet keypool empty");
|
||||||
CBlock *pblock = &pblocktemplate->block;
|
CBlock *pblock = &pblocktemplate->block;
|
||||||
@@ -275,8 +290,15 @@ Value setgenerate(const Array& params, bool fHelp)
|
|||||||
+ HelpExampleRpc("setgenerate", "true, 1")
|
+ HelpExampleRpc("setgenerate", "true, 1")
|
||||||
);
|
);
|
||||||
|
|
||||||
if (pwalletMain == NULL)
|
if (GetArg("-mineraddress", "").empty()) {
|
||||||
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
|
#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())
|
if (Params().MineBlocksOnDemand())
|
||||||
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Use the generate method instead of setgenerate on this network");
|
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["-gen"] = (fGenerate ? "1" : "0");
|
||||||
mapArgs ["-genproclimit"] = itostr(nGenProcLimit);
|
mapArgs ["-genproclimit"] = itostr(nGenProcLimit);
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
GenerateBitcoins(fGenerate, pwalletMain, nGenProcLimit);
|
GenerateBitcoins(fGenerate, pwalletMain, nGenProcLimit);
|
||||||
|
#else
|
||||||
|
GenerateBitcoins(fGenerate, nGenProcLimit);
|
||||||
|
#endif
|
||||||
|
|
||||||
return Value::null;
|
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("pooledtx", (uint64_t)mempool.size()));
|
||||||
obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC()));
|
obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC()));
|
||||||
obj.push_back(Pair("chain", Params().NetworkIDString()));
|
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)));
|
obj.push_back(Pair("generate", getgenerate(params, false)));
|
||||||
#endif
|
#endif
|
||||||
return obj;
|
return obj;
|
||||||
@@ -401,7 +427,6 @@ static Value BIP22ValidationResult(const CValidationState& state)
|
|||||||
return "valid?";
|
return "valid?";
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_WALLET
|
|
||||||
Value getblocktemplate(const Array& params, bool fHelp)
|
Value getblocktemplate(const Array& params, bool fHelp)
|
||||||
{
|
{
|
||||||
if (fHelp || params.size() > 1)
|
if (fHelp || params.size() > 1)
|
||||||
@@ -466,10 +491,15 @@ Value getblocktemplate(const Array& params, bool fHelp)
|
|||||||
|
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
|
|
||||||
|
// Wallet or miner address is required because we support coinbasetxn
|
||||||
|
if (GetArg("-mineraddress", "").empty()) {
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
// Wallet is required because we support coinbasetxn
|
if (!pwalletMain) {
|
||||||
if (pwalletMain == NULL) {
|
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Wallet disabled and -mineraddress not set");
|
||||||
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (wallet disabled)");
|
}
|
||||||
|
#else
|
||||||
|
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "zcashd compiled without wallet and -mineraddress not set");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string strMode = "template";
|
std::string strMode = "template";
|
||||||
@@ -599,8 +629,12 @@ Value getblocktemplate(const Array& params, bool fHelp)
|
|||||||
delete pblocktemplate;
|
delete pblocktemplate;
|
||||||
pblocktemplate = NULL;
|
pblocktemplate = NULL;
|
||||||
}
|
}
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
CReserveKey reservekey(pwalletMain);
|
CReserveKey reservekey(pwalletMain);
|
||||||
pblocktemplate = CreateNewBlockWithKey(reservekey);
|
pblocktemplate = CreateNewBlockWithKey(reservekey);
|
||||||
|
#else
|
||||||
|
pblocktemplate = CreateNewBlockWithKey();
|
||||||
|
#endif
|
||||||
if (!pblocktemplate)
|
if (!pblocktemplate)
|
||||||
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
|
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)));
|
result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1)));
|
||||||
|
|
||||||
return result;
|
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
|
class submitblock_StateCatcher : public CValidationInterface
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -313,7 +313,7 @@ static const CRPCCommand vRPCCommands[] =
|
|||||||
{ "mining", "submitblock", &submitblock, true },
|
{ "mining", "submitblock", &submitblock, true },
|
||||||
{ "mining", "getblocksubsidy", &getblocksubsidy, true },
|
{ "mining", "getblocksubsidy", &getblocksubsidy, true },
|
||||||
|
|
||||||
#if defined(ENABLE_WALLET) && defined(ENABLE_MINING)
|
#ifdef ENABLE_MINING
|
||||||
/* Coin generation */
|
/* Coin generation */
|
||||||
{ "generating", "getgenerate", &getgenerate, true },
|
{ "generating", "getgenerate", &getgenerate, true },
|
||||||
{ "generating", "setgenerate", &setgenerate, true },
|
{ "generating", "setgenerate", &setgenerate, true },
|
||||||
|
|||||||
@@ -1059,7 +1059,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ReturnKey();
|
void ReturnKey();
|
||||||
bool GetReservedKey(CPubKey &pubkey);
|
virtual bool GetReservedKey(CPubKey &pubkey);
|
||||||
void KeepKey();
|
void KeepKey();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user