#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"
#include "wallet/wallet.h"
#include "wallet/walletdb.h"
#endif
-
#include <stdint.h>
#include <stdio.h>
#include "libsnark/common/profiling.hpp"
+#if ENABLE_ZMQ
+#include "zmq/zmqnotificationinterface.h"
+#endif
+
using namespace std;
extern void ThreadSendAlert();
#endif
bool fFeeEstimatesInitialized = false;
+#if ENABLE_ZMQ
+static CZMQNotificationInterface* pzmqNotificationInterface = NULL;
+#endif
+
#ifdef WIN32
// Win32 LevelDB doesn't use file descriptors, and the ones used for
// accessing block files don't count towards the fd_set size limit
#ifdef ENABLE_WALLET
if (pwalletMain)
pwalletMain->Flush(false);
+#endif
+#ifdef ENABLE_MINING
+ #ifdef ENABLE_WALLET
GenerateBitcoins(false, NULL, 0);
+ #else
+ GenerateBitcoins(false, 0);
+ #endif
#endif
StopNode();
UnregisterNodeSignals(GetNodeSignals());
if (pwalletMain)
pwalletMain->Flush(true);
#endif
+
+#if ENABLE_ZMQ
+ if (pzmqNotificationInterface) {
+ UnregisterValidationInterface(pzmqNotificationInterface);
+ delete pzmqNotificationInterface;
+ pzmqNotificationInterface = NULL;
+ }
+#endif
+
#ifndef WIN32
try {
boost::filesystem::remove(GetPidFile());
#endif
}
strUsage += HelpMessageOpt("-datadir=<dir>", _("Specify data directory"));
+ strUsage += HelpMessageOpt("-exportdir=<dir>", _("Specify directory to be used when exporting data"));
strUsage += HelpMessageOpt("-dbcache=<n>", strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache));
strUsage += HelpMessageOpt("-loadblock=<file>", _("Imports blocks from external blk000??.dat file") + " " + _("on startup"));
strUsage += HelpMessageOpt("-maxorphantx=<n>", strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS));
strUsage += HelpMessageOpt("-timeout=<n>", strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT));
#ifdef USE_UPNP
#if USE_UPNP
- strUsage += HelpMessageOpt("-upnp", _("Use UPnP to map the listening port (default: 1 when listening)"));
+ strUsage += HelpMessageOpt("-upnp", _("Use UPnP to map the listening port (default: 1 when listening and no -proxy)"));
#else
strUsage += HelpMessageOpt("-upnp", strprintf(_("Use UPnP to map the listening port (default: %u)"), 0));
#endif
strUsage += HelpMessageOpt("-walletnotify=<cmd>", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)"));
strUsage += HelpMessageOpt("-zapwallettxes=<mode>", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") +
" " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)"));
-
+#endif
+
+#if ENABLE_ZMQ
+ strUsage += HelpMessageGroup(_("ZeroMQ notification options:"));
+ strUsage += HelpMessageOpt("-zmqpubhashblock=<address>", _("Enable publish hash block in <address>"));
+ strUsage += HelpMessageOpt("-zmqpubhashtx=<address>", _("Enable publish hash transaction in <address>"));
+ strUsage += HelpMessageOpt("-zmqpubrawblock=<address>", _("Enable publish raw block in <address>"));
+ strUsage += HelpMessageOpt("-zmqpubrawtx=<address>", _("Enable publish raw transaction in <address>"));
#endif
strUsage += HelpMessageGroup(_("Debugging/Testing options:"));
if (showDebug)
{
- strUsage += HelpMessageOpt("-checkpoints", strprintf("Only accept block chain matching built-in checkpoints (default: %u)", 1));
+ strUsage += HelpMessageOpt("-checkpoints", strprintf("Disable expensive verification for known chain history (default: %u)", 1));
strUsage += HelpMessageOpt("-dblogsize=<n>", strprintf("Flush database activity from memory pool to disk log every <n> megabytes (default: %u)", 100));
strUsage += HelpMessageOpt("-disablesafemode", strprintf("Disable safemode, override a real safe mode event (default: %u)", 0));
strUsage += HelpMessageOpt("-testsafemode", strprintf("Force safe mode (default: %u)", 0));
strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", 1));
strUsage += HelpMessageOpt("-stopafterblockimport", strprintf("Stop running after importing blocks from disk (default: %u)", 0));
}
- string debugCategories = "addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, net, proxy, prune"; // Don't translate these and qt below
+ string debugCategories = "addrman, alert, bench, coindb, db, estimatefee, lock, mempool, net, partitioncheck, pow, proxy, prune, "
+ "rand, reindex, rpc, selectcoins, zmq, zrpc, zrpcunsafe (implies zrpc)"; // Don't translate these and qt below
if (mode == HMM_BITCOIN_QT)
debugCategories += ", qt";
strUsage += HelpMessageOpt("-debug=<category>", strprintf(_("Output debugging information (default: %u, supplying <category> is optional)"), 0) + ". " +
- _("If <category> is not supplied, output all debugging information.") + _("<category> can be:") + " " + debugCategories + ".");
-#ifdef ENABLE_WALLET
- strUsage += HelpMessageOpt("-gen", strprintf(_("Generate coins (default: %u)"), 0));
- strUsage += HelpMessageOpt("-genproclimit=<n>", strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), 1));
- strUsage += HelpMessageOpt("-equihashsolver=<name>", _("Specify the Equihash solver to be used if enabled (default: \"default\")"));
-#endif
+ _("If <category> is not supplied or if <category> = 1, output all debugging information.") + " " + _("<category> can be:") + " " + debugCategories + ".");
+ strUsage += HelpMessageOpt("-experimentalfeatures", _("Enable use of experimental features"));
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));
strUsage += HelpMessageOpt("-blockminsize=<n>", strprintf(_("Set minimum block size in bytes (default: %u)"), 0));
strUsage += HelpMessageOpt("-blockmaxsize=<n>", strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE));
strUsage += HelpMessageOpt("-blockprioritysize=<n>", strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE));
+ if (GetBoolArg("-help-debug", false))
+ strUsage += HelpMessageOpt("-blockversion=<n>", strprintf("Override block version to test forking scenarios (default: %d)", (int)CBlock::CURRENT_VERSION));
+
+#ifdef ENABLE_MINING
+ strUsage += HelpMessageGroup(_("Mining options:"));
+ strUsage += HelpMessageOpt("-gen", strprintf(_("Generate coins (default: %u)"), 0));
+ strUsage += HelpMessageOpt("-genproclimit=<n>", strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), 1));
+ strUsage += HelpMessageOpt("-equihashsolver=<name>", _("Specify the Equihash solver to be used if enabled (default: \"default\")"));
+ strUsage += HelpMessageOpt("-mineraddress=<addr>", _("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("-min", _("Start minimized"));
strUsage += HelpMessageOpt("-rootcertificates=<file>", _("Set SSL root certificates for payment request (default: -system-)"));
strUsage += HelpMessageOpt("-splash", _("Show splash screen on startup (default: 1)"));
+ } else if (mode == HMM_BITCOIND) {
+ strUsage += HelpMessageGroup(_("Metrics Options (only if -daemon and -printtoconsole are not set):"));
+ strUsage += HelpMessageOpt("-showmetrics", _("Show metrics on stdout (default: 1 if running in a console, 0 otherwise)"));
+ strUsage += HelpMessageOpt("-metricsui", _("Set to 1 for a persistent metrics screen, 0 for sequential metrics output (default: 1 if running in a console, 0 otherwise)"));
+ strUsage += HelpMessageOpt("-metricsrefreshtime", strprintf(_("Number of seconds between metrics refreshes (default: %u if running in a console, %u otherwise)"), 1, 600));
}
return strUsage;
}
-std::string LicenseInfo()
-{
- return FormatParagraph(strprintf(_("Copyright (C) 2009-%i The Bitcoin Core Developers"), COPYRIGHT_YEAR)) + "\n" +
- FormatParagraph(strprintf(_("Copyright (C) 2015-%i The Zcash Developers"), COPYRIGHT_YEAR)) + "\n" +
- "\n" +
- FormatParagraph(_("This is experimental software.")) + "\n" +
- "\n" +
- FormatParagraph(_("Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.")) + "\n" +
- "\n" +
- FormatParagraph(_("This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.")) +
- "\n";
-}
-
static void BlockNotifyCallback(const uint256& hashNewTip)
{
std::string strCmd = GetArg("-blocknotify", "");
RenameThread("zcash-loadblk");
// -reindex
if (fReindex) {
-#ifdef ENABLE_WALLET
- if (pwalletMain) {
- pwalletMain->ClearNoteWitnessCache();
- }
-#endif
CImportingNow imp;
int nFile = 0;
while (true) {
}
// -loadblock=
- BOOST_FOREACH(boost::filesystem::path &path, vImportFiles) {
+ BOOST_FOREACH(const boost::filesystem::path& path, vImportFiles) {
FILE *file = fopen(path.string().c_str(), "rb");
if (file) {
CImportingNow imp;
boost::filesystem::path pk_path = ZC_GetParamsDir() / "sprout-proving.key";
boost::filesystem::path vk_path = ZC_GetParamsDir() / "sprout-verifying.key";
+ if (!(boost::filesystem::exists(pk_path) && boost::filesystem::exists(vk_path))) {
+ uiInterface.ThreadSafeMessageBox(strprintf(
+ _("Cannot find the Zcash network parameters in the following directory:\n"
+ "%s\n"
+ "Please run 'zcash-fetch-params' or './zcutil/fetch-params.sh' and then restart."),
+ ZC_GetParamsDir()),
+ "", CClientUIInterface::MSG_ERROR);
+ StartShutdown();
+ return;
+ }
+
pzcashParams = ZCJoinSplit::Unopened();
LogPrintf("Loading verifying key from %s\n", vk_path.string().c_str());
// ********************************************************* Step 2: parameter interactions
const CChainParams& chainparams = Params();
+ // Set this early so that experimental features are correctly enabled/disabled
+ fExperimentalMode = GetBoolArg("-experimentalfeatures", false);
+
+ // Fail early if user has set experimental options without the global flag
+ if (!fExperimentalMode) {
+ if (mapArgs.count("-developerencryptwallet")) {
+ return InitError(_("Wallet encryption requires -experimentalfeatures."));
+ }
+ }
+
// Set this early so that parameter interactions go to console
fPrintToConsole = GetBoolArg("-printtoconsole", false);
fLogTimestamps = GetBoolArg("-logtimestamps", true);
fLogIPs = GetBoolArg("-logips", false);
+ LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
+ LogPrintf("Zcash version %s (%s)\n", FormatFullVersion(), CLIENT_DATE);
+
// when specifying an explicit binding address, you want to listen on it
// even when -connect or -proxy is specified
if (mapArgs.count("-bind")) {
if (GetBoolArg("-nodebug", false) || find(categories.begin(), categories.end(), string("0")) != categories.end())
fDebug = false;
+ // Special case: if debug=zrpcunsafe, implies debug=zrpc, so add it to debug categories
+ if (find(categories.begin(), categories.end(), string("zrpcunsafe")) != categories.end()) {
+ if (find(categories.begin(), categories.end(), string("zrpc")) == categories.end()) {
+ LogPrintf("%s: parameter interaction: setting -debug=zrpcunsafe -> -debug=zrpc\n", __func__);
+ vector<string>& v = mapMultiArgs["-debug"];
+ v.push_back("zrpc");
+ }
+ }
+
// Check for -debugnet
if (GetBoolArg("-debugnet", false))
InitWarning(_("Warning: Unsupported argument -debugnet ignored, use -debug=net."));
fAlerts = GetBoolArg("-alerts", DEFAULT_ALERTS);
+ // Option to startup with mocktime set (used for regression testing):
+ SetMockTime(GetArg("-mocktime", 0)); // SetMockTime(0) is a no-op
+
+#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
// Initialize libsodium
#endif
if (GetBoolArg("-shrinkdebugfile", !fDebug))
ShrinkDebugFile();
- LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
- LogPrintf("Zcash version %s (%s)\n", FormatFullVersion(), CLIENT_DATE);
+
+ if (fPrintToDebugLog)
+ OpenDebugLog();
+
LogPrintf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION));
#ifdef ENABLE_WALLET
LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0));
CScheduler::Function serviceLoop = boost::bind(&CScheduler::serviceQueue, &scheduler);
threadGroup.create_thread(boost::bind(&TraceThread<CScheduler::Function>, "scheduler", serviceLoop));
+ // Count uptime
+ MarkStartTime();
+
if ((chainparams.NetworkIDString() != "regtest") &&
- GetBoolArg("-showmetrics", true) &&
+ GetBoolArg("-showmetrics", isatty(STDOUT_FILENO)) &&
!fPrintToConsole && !GetBoolArg("-daemon", false)) {
// Start the persistent metrics interface
ConnectMetricsScreen();
std::string warningString;
std::string errorString;
-
+
if (!CWallet::Verify(strWalletFile, warningString, errorString))
return false;
-
+
if (!warningString.empty())
InitWarning(warningString);
if (!errorString.empty())
return InitError(warningString);
-
+
} // (!fDisableWallet)
#endif // ENABLE_WALLET
// ********************************************************* Step 6: network initialization
if (mapArgs.count("-onlynet")) {
std::set<enum Network> nets;
- BOOST_FOREACH(std::string snet, mapMultiArgs["-onlynet"]) {
+ BOOST_FOREACH(const std::string& snet, mapMultiArgs["-onlynet"]) {
enum Network net = ParseNetwork(snet);
if (net == NET_UNROUTABLE)
return InitError(strprintf(_("Unknown network specified in -onlynet: '%s'"), snet));
}
}
- proxyType addrProxy;
- bool fProxy = false;
- if (mapArgs.count("-proxy")) {
- addrProxy = proxyType(CService(mapArgs["-proxy"], 9050), GetBoolArg("-proxyrandomize", true));
+ bool proxyRandomize = GetBoolArg("-proxyrandomize", true);
+ // -proxy sets a proxy for all outgoing network traffic
+ // -noproxy (or -proxy=0) as well as the empty string can be used to not set a proxy, this is the default
+ std::string proxyArg = GetArg("-proxy", "");
+ if (proxyArg != "" && proxyArg != "0") {
+ proxyType addrProxy = proxyType(CService(proxyArg, 9050), proxyRandomize);
if (!addrProxy.IsValid())
- return InitError(strprintf(_("Invalid -proxy address: '%s'"), mapArgs["-proxy"]));
+ return InitError(strprintf(_("Invalid -proxy address: '%s'"), proxyArg));
SetProxy(NET_IPV4, addrProxy);
SetProxy(NET_IPV6, addrProxy);
+ SetProxy(NET_TOR, addrProxy);
SetNameProxy(addrProxy);
- fProxy = true;
+ SetReachable(NET_TOR); // by default, -proxy sets onion as reachable, unless -noonion later
}
- // -onion can override normal proxy, -noonion disables connecting to .onion entirely
- if (!(mapArgs.count("-onion") && mapArgs["-onion"] == "0") &&
- (fProxy || mapArgs.count("-onion"))) {
- proxyType addrOnion;
- if (!mapArgs.count("-onion"))
- addrOnion = addrProxy;
- else
- addrOnion = proxyType(CService(mapArgs["-onion"], 9050), GetBoolArg("-proxyrandomize", true));
- if (!addrOnion.IsValid())
- return InitError(strprintf(_("Invalid -onion address: '%s'"), mapArgs["-onion"]));
- SetProxy(NET_TOR, addrOnion);
- SetReachable(NET_TOR);
+ // -onion can be used to set only a proxy for .onion, or override normal proxy for .onion addresses
+ // -noonion (or -onion=0) disables connecting to .onion entirely
+ // An empty string is used to not override the onion proxy (in which case it defaults to -proxy set above, or none)
+ std::string onionArg = GetArg("-onion", "");
+ if (onionArg != "") {
+ if (onionArg == "0") { // Handle -noonion/-onion=0
+ SetReachable(NET_TOR, false); // set onions as unreachable
+ } else {
+ proxyType addrOnion = proxyType(CService(onionArg, 9050), proxyRandomize);
+ if (!addrOnion.IsValid())
+ return InitError(strprintf(_("Invalid -onion address: '%s'"), onionArg));
+ SetProxy(NET_TOR, addrOnion);
+ SetReachable(NET_TOR);
+ }
}
// see Step 2: parameter interactions for more information about these
bool fBound = false;
if (fListen) {
if (mapArgs.count("-bind") || mapArgs.count("-whitebind")) {
- BOOST_FOREACH(std::string strBind, mapMultiArgs["-bind"]) {
+ BOOST_FOREACH(const std::string& strBind, mapMultiArgs["-bind"]) {
CService addrBind;
if (!Lookup(strBind.c_str(), addrBind, GetListenPort(), false))
return InitError(strprintf(_("Cannot resolve -bind address: '%s'"), strBind));
fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR));
}
- BOOST_FOREACH(std::string strBind, mapMultiArgs["-whitebind"]) {
+ BOOST_FOREACH(const std::string& strBind, mapMultiArgs["-whitebind"]) {
CService addrBind;
if (!Lookup(strBind.c_str(), addrBind, 0, false))
return InitError(strprintf(_("Cannot resolve -whitebind address: '%s'"), strBind));
}
if (mapArgs.count("-externalip")) {
- BOOST_FOREACH(string strAddr, mapMultiArgs["-externalip"]) {
+ BOOST_FOREACH(const std::string& strAddr, mapMultiArgs["-externalip"]) {
CService addrLocal(strAddr, GetListenPort(), fNameLookup);
if (!addrLocal.IsValid())
return InitError(strprintf(_("Cannot resolve -externalip address: '%s'"), strAddr));
}
}
- BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"])
+ BOOST_FOREACH(const std::string& strDest, mapMultiArgs["-seednode"])
AddOneShot(strDest);
+#if ENABLE_ZMQ
+ pzmqNotificationInterface = CZMQNotificationInterface::CreateWithArguments(mapArgs);
+
+ if (pzmqNotificationInterface) {
+ RegisterValidationInterface(pzmqNotificationInterface);
+ }
+#endif
+
// ********************************************************* Step 7: load block chain
fReindex = GetBoolArg("-reindex", false);
if (!fLoaded) {
// first suggest a reindex
if (!fReset) {
- bool fRet = uiInterface.ThreadSafeMessageBox(
+ bool fRet = uiInterface.ThreadSafeQuestion(
strLoadError + ".\n\n" + _("Do you want to rebuild the block database now?"),
+ strLoadError + ".\nPlease restart with -reindex to recover.",
"", CClientUIInterface::MSG_ERROR | CClientUIInterface::BTN_ABORT);
if (fRet) {
fReindex = true;
if (fFirstRun)
{
// Create new keyUser and set as default key
- RandAddSeedPerfmon();
-
CPubKey newDefaultKey;
if (pwalletMain->GetKeyFromPool(newDefaultKey)) {
pwalletMain->SetDefaultKey(newDefaultKey);
CBlockIndex *pindexRescan = chainActive.Tip();
if (GetBoolArg("-rescan", false))
+ {
+ pwalletMain->ClearNoteWitnessCache();
pindexRescan = chainActive.Genesis();
+ }
else
{
CWalletDB walletdb(strWalletFile);
LogPrintf("No wallet support compiled in!\n");
#endif // !ENABLE_WALLET
+#ifdef ENABLE_MINING
+ #ifndef ENABLE_WALLET
+ if (GetBoolArg("-minetolocalwallet", false)) {
+ return InitError(_("Zcash was not built with wallet support. Set -minetolocalwallet=0 to use -mineraddress, or rebuild Zcash with wallet support."));
+ }
+ if (GetArg("-mineraddress", "").empty() && GetBoolArg("-gen", false)) {
+ 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
+ bool minerAddressInLocalWallet = false;
+ if (pwalletMain) {
+ // Address has alreday been validated
+ CBitcoinAddress addr(mapArgs["-mineraddress"]);
+ CKeyID keyID;
+ addr.GetKeyID(keyID);
+ minerAddressInLocalWallet = pwalletMain->HaveKey(keyID);
+ }
+ if (GetBoolArg("-minetolocalwallet", true) && !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
std::vector<boost::filesystem::path> vImportFiles;
if (mapArgs.count("-loadblock"))
{
- BOOST_FOREACH(string strFile, mapMultiArgs["-loadblock"])
+ BOOST_FOREACH(const std::string& strFile, mapMultiArgs["-loadblock"])
vImportFiles.push_back(strFile);
}
threadGroup.create_thread(boost::bind(&ThreadImport, vImportFiles));
if (!strErrors.str().empty())
return InitError(strErrors.str());
- RandAddSeedPerfmon();
-
//// debug print
LogPrintf("mapBlockIndex.size() = %u\n", mapBlockIndex.size());
LogPrintf("nBestHeight = %d\n", chainActive.Height());
boost::ref(cs_main), boost::cref(pindexBestHeader), nPowTargetSpacing);
scheduler.scheduleEvery(f, nPowTargetSpacing);
-#ifdef ENABLE_WALLET
+#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