// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or https://www.opensource.org/licenses/mit-license.php .
#if defined(HAVE_CONFIG_H)
#include "config/bitcoin-config.h"
#include "httprpc.h"
#include "key.h"
#include "notarisationdb.h"
-#ifdef ENABLE_MINING
#include "key_io.h"
-#endif
#include "main.h"
#include "metrics.h"
#include "miner.h"
#include "rpc/pbaasrpc.h"
#include "rpc/register.h"
#include "script/standard.h"
+#include "script/sigcache.h"
#include "scheduler.h"
#include "txdb.h"
#include "torcontrol.h"
#include "utilmoneystr.h"
#include "validationinterface.h"
#ifdef ENABLE_WALLET
+#include "key_io.h"
#include "wallet/wallet.h"
#include "wallet/walletdb.h"
#endif
extern void ThreadSendAlert();
extern int32_t KOMODO_LOADINGBLOCKS;
extern bool VERUS_MINTBLOCKS;
-extern std::string VERUS_CHEATCATCHER;
+extern std::string VERUS_DEFAULT_ZADDR;
ZCJoinSplit* pzcashParams = NULL;
#endif
#ifdef ENABLE_MINING
- #ifdef ENABLE_WALLET
+#ifdef ENABLE_WALLET
GenerateBitcoins(false, NULL, 0);
- #else
+#else
GenerateBitcoins(false, 0);
- #endif
+#endif
#endif
StopNode();
strUsage += HelpMessageGroup(_("Wallet options:"));
strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls"));
strUsage += HelpMessageOpt("-keypool=<n>", strprintf(_("Set key pool size to <n> (default: %u)"), 100));
+ strUsage += HelpMessageOpt("-migration", _("Enable the Sprout to Sapling migration"));
+ strUsage += HelpMessageOpt("-migrationdestaddress=<zaddr>", _("Set the Sapling migration address"));
if (showDebug)
strUsage += HelpMessageOpt("-mintxfee=<amt>", strprintf("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)",
CURRENCY_UNIT, FormatMoney(CWallet::minTxFee.GetFeePerK())));
strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0));
strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1));
strUsage += HelpMessageOpt("-txconfirmtarget=<n>", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET));
- strUsage += HelpMessageOpt("-txexpirydelta", strprintf(_("Set the number of blocks after which a transaction that has not been mined will become invalid (default: %u)"), DEFAULT_TX_EXPIRY_DELTA));
+ strUsage += HelpMessageOpt("-txexpirydelta", strprintf(_("Set the number of blocks after which a transaction that has not been mined will become invalid (min: %u, default: %u (pre-Blossom) or %u (post-Blossom))"), TX_EXPIRING_SOON_THRESHOLD + 1, DEFAULT_PRE_BLOSSOM_TX_EXPIRY_DELTA, DEFAULT_POST_BLOSSOM_TX_EXPIRY_DELTA));
strUsage += HelpMessageOpt("-maxtxfee=<amt>", strprintf(_("Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)"),
CURRENCY_UNIT, FormatMoney(maxTxFee)));
strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format") + " " + _("on startup"));
{
strUsage += HelpMessageOpt("-limitfreerelay=<n>", strprintf("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default: %u)", 15));
strUsage += HelpMessageOpt("-relaypriority", strprintf("Require high priority for relaying free or low-fee transactions (default: %u)", 0));
- strUsage += HelpMessageOpt("-maxsigcachesize=<n>", strprintf("Limit size of signature cache to <n> entries (default: %u)", 50000));
+ strUsage += HelpMessageOpt("-maxsigcachesize=<n>", strprintf("Limit size of signature cache to <n> MiB (default: %u)", DEFAULT_MAX_SIG_CACHE_SIZE));
strUsage += HelpMessageOpt("-maxtipage=<n>", strprintf("Maximum tip age in seconds to consider node in initial block download (default: %u)", DEFAULT_MAX_TIP_AGE));
}
strUsage += HelpMessageOpt("-minrelaytxfee=<amt>", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for relaying (default: %s)"),
strUsage += HelpMessageOpt("-regtest", "Enter regression test mode, which uses a special chain in which blocks can be solved instantly. "
"This is intended for regression testing tools and app development.");
}
- strUsage += HelpMessageOpt("-shrinkdebugfile", _("Shrink debug.log file on client startup (default: 1 when no -debug)"));
+ // strUsage += HelpMessageOpt("-shrinkdebugfile", _("Shrink debug.log file on client startup (default: 1 when no -debug)"));
strUsage += HelpMessageOpt("-testnet", _("Use the test network"));
strUsage += HelpMessageGroup(_("Node relay options:"));
void ThreadImport(std::vector<boost::filesystem::path> vImportFiles)
{
+ const CChainParams& chainparams = Params();
RenameThread("zcash-loadblk");
// -reindex
if (fReindex) {
if (!file)
break; // This error is logged in OpenBlockFile
LogPrintf("Reindexing block file blk%05u.dat...\n", (unsigned int)nFile);
- LoadExternalBlockFile(file, &pos);
+ LoadExternalBlockFile(chainparams, file, &pos);
nFile++;
}
pblocktree->WriteReindexing(false);
fReindex = false;
LogPrintf("Reindexing finished\n");
// To avoid ending up in a situation without genesis block, re-try initializing (no-op if reindexing worked):
- InitBlockIndex();
+ InitBlockIndex(chainparams);
KOMODO_LOADINGBLOCKS = 0;
}
CImportingNow imp;
boost::filesystem::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old";
LogPrintf("Importing bootstrap.dat...\n");
- LoadExternalBlockFile(file);
+ LoadExternalBlockFile(chainparams, file);
RenameOver(pathBootstrap, pathBootstrapOld);
} else {
LogPrintf("Warning: Could not open bootstrap file %s\n", pathBootstrap.string());
if (file) {
CImportingNow imp;
LogPrintf("Importing blocks file %s...\n", path.string());
- LoadExternalBlockFile(file);
+ LoadExternalBlockFile(chainparams, file);
} else {
LogPrintf("Warning: Could not open blocks file %s\n", path.string());
}
}
}
+void ThreadNotifyRecentlyAdded()
+{
+ while (true) {
+ // Run the notifier on an integer second in the steady clock.
+ auto now = std::chrono::steady_clock::now().time_since_epoch();
+ auto nextFire = std::chrono::duration_cast<std::chrono::seconds>(
+ now + std::chrono::seconds(1));
+ std::this_thread::sleep_until(
+ std::chrono::time_point<std::chrono::steady_clock>(nextFire));
+
+ boost::this_thread::interruption_point();
+
+ mempool.NotifyRecentlyAdded();
+ }
+}
+
/** Sanity checks
* Ensure that Bitcoin is running in a usable environment with all
* necessary library support.
if (!fExperimentalMode) {
if (mapArgs.count("-developerencryptwallet")) {
return InitError(_("Wallet encryption requires -experimentalfeatures."));
- }
- else if (mapArgs.count("-paymentdisclosure")) {
+ } else if (mapArgs.count("-developersetpoolsizezero")) {
+ return InitError(_("Setting the size of shielded pools to zero requires -experimentalfeatures."));
+ } else if (mapArgs.count("-paymentdisclosure")) {
return InitError(_("Payment disclosure requires -experimentalfeatures."));
} else if (mapArgs.count("-zmergetoaddress")) {
return InitError(_("RPC method z_mergetoaddress requires -experimentalfeatures."));
+ } else if (mapArgs.count("-savesproutr1cs")) {
+ return InitError(_("Saving the Sprout R1CS requires -experimentalfeatures."));
}
}
}
}
nTxConfirmTarget = GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET);
- expiryDelta = GetArg("-txexpirydelta", DEFAULT_TX_EXPIRY_DELTA);
+ if (mapArgs.count("-txexpirydelta")) {
+ int64_t expiryDelta = atoi64(mapArgs["-txexpirydelta"]);
+ uint32_t minExpiryDelta = TX_EXPIRING_SOON_THRESHOLD + 1;
+ if (expiryDelta < minExpiryDelta) {
+ return InitError(strprintf(_("Invalid value for -txexpirydelta='%u' (must be least %u)"), expiryDelta, minExpiryDelta));
+ }
+ expiryDeltaArg = expiryDelta;
+ }
bSpendZeroConfChange = GetBoolArg("-spendzeroconfchange", true);
fSendFreeTransactions = GetBoolArg("-sendfreetransactions", false);
std::string strWalletFile = GetArg("-wallet", "wallet.dat");
+ // Check Sapling migration address if set and is a valid Sapling address
+ if (mapArgs.count("-migrationdestaddress")) {
+ std::string migrationDestAddress = mapArgs["-migrationdestaddress"];
+ libzcash::PaymentAddress address = DecodePaymentAddress(migrationDestAddress);
+ if (boost::get<libzcash::SaplingPaymentAddress>(&address) == nullptr) {
+ return InitError(_("-migrationdestaddress must be a valid Sapling address."));
+ }
+ }
#endif // ENABLE_WALLET
fIsBareMultisigStd = GetBoolArg("-permitbaremultisig", true);
CVerusHash::init();
CVerusHashV2::init();
CBlockHeader::SetVerusV2Hash();
- if (strcmp(ASSETCHAINS_SYMBOL,"VRSC") == 0)
+ if (IsVerusMainnetActive())
{
CConstVerusSolutionVector::activationHeight.SetActivationHeight(CActivationHeight::SOLUTION_VERUSV2, 310000);
+ CConstVerusSolutionVector::activationHeight.SetActivationHeight(CActivationHeight::SOLUTION_VERUSV3, 800200);
+ CConstVerusSolutionVector::activationHeight.SetActivationHeight(CActivationHeight::SOLUTION_VERUSV4, 800200);
+ CConstVerusSolutionVector::activationHeight.SetActivationHeight(CActivationHeight::SOLUTION_VERUSV5, 1053660);
+ CConstVerusSolutionVector::activationHeight.SetActivationHeight(CActivationHeight::SOLUTION_VERUSV5_1, 1053660);
+ }
+ else if (IsVerusActive())
+ {
+ CConstVerusSolutionVector::activationHeight.SetActivationHeight(CActivationHeight::SOLUTION_VERUSV2, 1);
+ CConstVerusSolutionVector::activationHeight.SetActivationHeight(CActivationHeight::SOLUTION_VERUSV3, 1);
+ CConstVerusSolutionVector::activationHeight.SetActivationHeight(CActivationHeight::SOLUTION_VERUSV4, 1);
+ CConstVerusSolutionVector::activationHeight.SetActivationHeight(CActivationHeight::SOLUTION_VERUSV5, 1);
+ CConstVerusSolutionVector::activationHeight.SetActivationHeight(CActivationHeight::SOLUTION_VERUSV5_1, 1);
+ CConstVerusSolutionVector::activationHeight.SetActivationHeight(CActivationHeight::SOLUTION_VERUSV6, 1);
}
else
{
CConstVerusSolutionVector::activationHeight.SetActivationHeight(CActivationHeight::SOLUTION_VERUSV2, 1);
CConstVerusSolutionVector::activationHeight.SetActivationHeight(CActivationHeight::SOLUTION_VERUSV3, 1);
+ CConstVerusSolutionVector::activationHeight.SetActivationHeight(CActivationHeight::SOLUTION_VERUSV4, 1);
+ CConstVerusSolutionVector::activationHeight.SetActivationHeight(CActivationHeight::SOLUTION_VERUSV5, 1);
+ CConstVerusSolutionVector::activationHeight.SetActivationHeight(CActivationHeight::SOLUTION_VERUSV5_1, 1);
+ CConstVerusSolutionVector::activationHeight.SetActivationHeight(CActivationHeight::SOLUTION_VERUSV6, 1);
}
}
+ // get default IDs and addresses
+ auto defaultIDDest = DecodeDestination(GetArg("-defaultid", ""));
+ VERUS_DEFAULTID = defaultIDDest.which() == COptCCParams::ADDRTYPE_ID ? CIdentityID(GetDestinationID(defaultIDDest)) : CIdentityID();
+ auto notaryIDDest = DecodeDestination(GetArg("-notaryid", ""));
+ VERUS_NOTARYID = notaryIDDest.which() == COptCCParams::ADDRTYPE_ID ? CIdentityID(GetDestinationID(notaryIDDest)) : CIdentityID();
+ auto nodeIDDest = DecodeDestination(GetArg("-nodeid", ""));
+ VERUS_NODEID = nodeIDDest.which() == COptCCParams::ADDRTYPE_ID ? GetDestinationID(nodeIDDest) : uint160();
+ VERUS_DEFAULT_ZADDR = GetArg("-cheatcatcher", "");
+ VERUS_DEFAULT_ZADDR = GetArg("-defaultzaddr", VERUS_DEFAULT_ZADDR);
+ MAX_OUR_UTXOS_ID_RESCAN = GetArg("-maxourutxosidrescan", MAX_OUR_UTXOS_ID_RESCAN);
+ MAX_UTXOS_ID_RESCAN = GetArg("-maxutxosidrescan", std::min(MAX_UTXOS_ID_RESCAN, MAX_OUR_UTXOS_ID_RESCAN));
+
+ // if we are supposed to catch stake cheaters, there must be a valid sapling parameter, we need it at
+ // initialization, and this is the first time we can get it. store the Sapling address here
+ extern boost::optional<libzcash::SaplingPaymentAddress> defaultSaplingDest;
+ libzcash::PaymentAddress addr = DecodePaymentAddress(VERUS_DEFAULT_ZADDR);
+ if (VERUS_DEFAULT_ZADDR.size() > 0 && IsValidPaymentAddress(addr))
+ {
+ try
+ {
+ defaultSaplingDest = boost::get<libzcash::SaplingPaymentAddress>(addr);
+ }
+ catch (...)
+ {
+ }
+ }
+ VERUS_PRIVATECHANGE = GetBoolArg("-privatechange", !GetArg("-defaultzaddr", VERUS_DEFAULT_ZADDR).empty());
+
// Sanity check
if (!InitSanityCheck())
- return InitError(_("Initialization sanity check failed. Komodo is shutting down."));
+ return InitError(_("Initialization sanity check failed. Verus is shutting down."));
std::string strDataDir = GetDataDir().string();
#ifdef ENABLE_WALLET
try {
static boost::interprocess::file_lock lock(pathLockFile.string().c_str());
if (!lock.try_lock())
- return InitError(strprintf(_("Cannot obtain a lock on data directory %s. Komodo is probably already running."), strDataDir));
+ return InitError(strprintf(_("Cannot obtain a lock on data directory %s. Verus is probably already running."), strDataDir));
} catch(const boost::interprocess::interprocess_exception& e) {
- return InitError(strprintf(_("Cannot obtain a lock on data directory %s. Komodo is probably already running.") + " %s.", strDataDir, e.what()));
+ return InitError(strprintf(_("Cannot obtain a lock on data directory %s. Verus is probably already running.") + " %s.", strDataDir, e.what()));
}
#ifndef _WIN32
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("Komodo version %s (%s)\n", FormatFullVersion(), CLIENT_DATE);
+ LogPrintf("Verus version %s (%s)\n", FormatFullVersion(), CLIENT_DATE);
if (fPrintToDebugLog)
OpenDebugLog();
// Initialize Zcash circuit parameters
ZC_LoadParams(chainparams);
+ if (GetBoolArg("-savesproutr1cs", false)) {
+ boost::filesystem::path r1cs_path = ZC_GetParamsDir() / "r1cs";
+
+ LogPrintf("Saving Sprout R1CS to %s\n", r1cs_path.string());
+
+ pzcashParams->saveR1CS(r1cs_path.string());
+ }
+
/* Start the RPC server already. It will be started in "warmup" mode
* and not really process calls already (but it will signify connections
* that the server is there and will be ready later). Warmup mode will
}
}
- BOOST_FOREACH(const std::string& strDest, mapMultiArgs["-seednode"])
- AddOneShot(strDest);
+ for (auto &oneNode : ConnectedChains.defaultPeerNodes)
+ {
+ AddOneShot(oneNode.networkAddress);
+ }
#if ENABLE_ZMQ
pzmqNotificationInterface = CZMQNotificationInterface::CreateWithArguments(mapArgs);
if ( fReindex == 0 )
{
- bool checkval,fAddressIndex,fSpentIndex;
+ bool checkval,fAddressIndex,fSpentIndex,fTimeStampIndex;
pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex, dbCompression, dbMaxOpenFiles);
- fAddressIndex = GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX);
+
+ fAddressIndex = true;
pblocktree->ReadFlag("addressindex", checkval);
if ( checkval != fAddressIndex )
{
fprintf(stderr,"set addressindex, will reindex. sorry will take a while.\n");
fReindex = true;
}
- fSpentIndex = GetBoolArg("-spentindex", DEFAULT_SPENTINDEX);
+
+ fSpentIndex = true;
pblocktree->ReadFlag("spentindex", checkval);
if ( checkval != fSpentIndex )
{
fprintf(stderr,"set spentindex, will reindex. sorry will take a while.\n");
fReindex = true;
}
+
+ fInsightExplorer = GetBoolArg("-insightexplorer", DEFAULT_INSIGHTEXPLORER);
+ pblocktree->ReadFlag("insightexplorer", checkval);
+ if ( checkval != fInsightExplorer )
+ {
+ pblocktree->WriteFlag("insightexplorer", fInsightExplorer);
+ fprintf(stderr,"set insightexplorer, will reindex. sorry will take a while.\n");
+ fReindex = true;
+ }
+
+ fTimeStampIndex = GetBoolArg("-timestampindex", DEFAULT_TIMESTAMPINDEX);
+ pblocktree->ReadFlag("timestampindex", checkval);
+ if ( checkval != fTimeStampIndex )
+ {
+ pblocktree->WriteFlag("timestampindex", fTimeStampIndex);
+ fprintf(stderr,"set timestampindex, will reindex. sorry will take a while.\n");
+ fReindex = true;
+ }
}
bool clearWitnessCaches = false;
return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?"));
// Initialize the block index (no-op if non-empty database was already loaded)
- if (!InitBlockIndex()) {
+ if (!InitBlockIndex(chainparams)) {
strLoadError = _("Error initializing block database");
break;
}
KOMODO_LOADINGBLOCKS = 0;
+
// Check for changed -txindex state
- if (fTxIndex != GetBoolArg("-txindex", true)) {
+ if (!fReindex && fTxIndex != GetBoolArg("-txindex", true)) {
strLoadError = _("You need to rebuild the database using -reindex to change -txindex");
break;
}
+ // Check for changed -insightexplorer state
+ if (!fReindex && fInsightExplorer != GetBoolArg("-insightexplorer", DEFAULT_INSIGHTEXPLORER) ) {
+ strLoadError = _("You need to rebuild the database using -reindex to change -insightexplorer");
+ break;
+ }
+
// Check for changed -prune state. What we are concerned about is a user who has pruned blocks
// in the past, but is now trying to run unpruned.
- if (fHavePruned && !fPruneMode) {
+ if (!fReindex && fHavePruned && !fPruneMode) {
strLoadError = _("You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain");
break;
}
}
if ( KOMODO_REWIND == 0 )
{
- if (!CVerifyDB().VerifyDB(pcoinsdbview, GetArg("-checklevel", 3),
+ if (!CVerifyDB().VerifyDB(Params(), pcoinsdbview, GetArg("-checklevel", 3),
GetArg("-checkblocks", 288))) {
strLoadError = _("Corrupted block database detected");
break;
if (!pwalletMain->HaveHDSeed())
{
- // generate a new HD seed
- pwalletMain->GenerateNewSeed();
+ // We can't set the new HD seed until the wallet is decrypted.
+ // https://github.com/zcash/zcash/issues/3607
+ if (!pwalletMain->IsCrypted()) {
+ // generate a new HD seed
+ pwalletMain->GenerateNewSeed();
+ }
}
+ // Set sapling migration status
+ pwalletMain->fSaplingMigrationEnabled = GetBoolArg("-migration", false);
+
if (fFirstRun)
{
// Create new keyUser and set as default key
#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."));
+ return InitError(_("Verus was not built with wallet support. Set -minetolocalwallet=0 to use -mineraddress, or rebuild Verus 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."));
+ return InitError(_("Verus was not built with wallet support. Set -mineraddress, or rebuild Verus with wallet support."));
}
#endif // !ENABLE_WALLET
#ifdef ENABLE_WALLET
bool minerAddressInLocalWallet = false;
if (pwalletMain) {
- // Address has alreday been validated
+ // Address has already been validated
CTxDestination addr = DecodeDestination(mapArgs["-mineraddress"]);
- CKeyID keyID = boost::get<CKeyID>(addr);
- minerAddressInLocalWallet = pwalletMain->HaveKey(keyID);
+ if (addr.which() == COptCCParams::ADDRTYPE_ID)
+ {
+ std::pair<CIdentityMapKey, CIdentityMapValue> keyAndIdentity;
+ minerAddressInLocalWallet = pwalletMain->GetIdentity(GetDestinationID(addr), keyAndIdentity) &&
+ keyAndIdentity.first.CanSpend();
+ }
+ else
+ {
+ CKeyID keyID = boost::get<CKeyID>(addr);
+ 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
+
+ // This is leveraging the fact that boost::signals2 executes connected
+ // handlers in-order. Further up, the wallet is connected to this signal
+ // if the wallet is enabled. The wallet's ScriptForMining handler does
+ // nothing if -mineraddress is set, and GetScriptForMinerAddress() does
+ // nothing if -mineraddress is not set (or set to an invalid address).
+ //
+ // The upshot is that when ScriptForMining(script) is called:
+ // - If -mineraddress is set (whether or not the wallet is enabled), the
+ // CScript argument is set to -mineraddress.
+ // - If the wallet is enabled and -mineraddress is not set, the CScript
+ // argument is set to a wallet address.
+ // - If the wallet is disabled and -mineraddress is not set, the CScript
+ // argument is not modified; in practice this means it is empty, and
+ // GenerateBitcoins() returns an error.
+ GetMainSignals().ScriptForMining.connect(GetScriptForMinerAddress);
}
#endif // ENABLE_MINING
uiInterface.InitMessage(_("Activating best chain..."));
// scan for better chains in the block chain database, that are not yet connected in the active best chain
CValidationState state;
- if ( !ActivateBestChain(state))
+ if ( !ActivateBestChain(state, Params()))
strErrors << "Failed to connect best block";
}
+ InitializePremineSupply();
std::vector<boost::filesystem::path> vImportFiles;
if (mapArgs.count("-loadblock"))
{
LogPrintf("mapAddressBook.size() = %u\n", pwalletMain ? pwalletMain->mapAddressBook.size() : 0);
#endif
+ // Start the thread that notifies listeners of transactions that have been
+ // recently added to the mempool.
+ threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "txnotify", &ThreadNotifyRecentlyAdded));
+
if (GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION))
StartTorControl(threadGroup, scheduler);
StartNode(threadGroup, scheduler);
- VERUS_CHEATCATCHER = GetArg("-cheatcatcher", "");
bool gen = GetBoolArg("-gen", false);
#ifdef ENABLE_MINING
GenerateBitcoins(gen, GetArg("-genproclimit", -1));
#endif
#endif
+
+ // Monitor the chain every minute, and alert if we get blocks much quicker or slower than expected.
+ CScheduler::Function f = boost::bind(&PartitionCheck, &IsInitialBlockDownload,
+ boost::ref(cs_main), boost::cref(pindexBestHeader));
+ scheduler.scheduleEvery(f, 60);
// ********************************************************* Step 11: finished