/** Initialize KikeKoin. * @pre Parameters should be parsed and config file should be read. */ bool AppInit2() { // ********************************************************* Step 1: setup #ifdef _MSC_VER // Turn off microsoft heap dump noise _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); #endif #if _MSC_VER >= 1400 // Disable confusing "helpful" text message on abort, ctrl-c _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); #endif #ifndef WIN32 umask(077); #endif #ifndef WIN32 // Clean shutdown on SIGTERM struct sigaction sa; sa.sa_handler = HandleSIGTERM; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sigaction(SIGTERM, &sa, NULL); sigaction(SIGINT, &sa, NULL); // Reopen debug.log on SIGHUP struct sigaction sa_hup; sa_hup.sa_handler = HandleSIGHUP; sigemptyset(&sa_hup.sa_mask); sa_hup.sa_flags = 0; sigaction(SIGHUP, &sa_hup, NULL); #endif // ********************************************************* Step 2: parameter interactions fTestNet = GetBoolArg("-testnet"); // Keep irc seeding on by default for now. // if (fTestNet) // { SoftSetBoolArg("-irc", true); // } if (mapArgs.count("-bind")) { // when specifying an explicit binding address, you want to listen on it // even when -connect or -proxy is specified SoftSetBoolArg("-listen", true); } if (mapArgs.count("-connect")) { // when only connecting to trusted nodes, do not seed via DNS, or listen by default SoftSetBoolArg("-dnsseed", false); SoftSetBoolArg("-listen", false); } if (mapArgs.count("-proxy")) { // to protect privacy, do not listen by default if a proxy server is specified SoftSetBoolArg("-listen", false); } if (!GetBoolArg("-listen", true)) { // do not map ports or try to retrieve public IP when not listening (pointless) SoftSetBoolArg("-upnp", false); SoftSetBoolArg("-discover", false); } if (mapArgs.count("-externalip")) { // if an explicit public IP is specified, do not try to find others SoftSetBoolArg("-discover", false); } // ********************************************************* Step 3: parameter-to-internal-flags fDebug = GetBoolArg("-debug"); // -debug implies fDebug* if (fDebug) fDebugNet = true; else fDebugNet = GetBoolArg("-debugnet"); bitdb.SetDetach(GetBoolArg("-detachdb", false)); #if !defined(WIN32) && !defined(QT_GUI) fDaemon = GetBoolArg("-daemon"); #else fDaemon = false; #endif if (fDaemon) fServer = true; else fServer = GetBoolArg("-server"); /* force fServer when running without GUI */ #if !defined(QT_GUI) fServer = true; #endif fPrintToConsole = GetBoolArg("-printtoconsole"); fPrintToDebugger = GetBoolArg("-printtodebugger"); fLogTimestamps = GetBoolArg("-logtimestamps"); if (mapArgs.count("-timeout")) { int nNewTimeout = GetArg("-timeout", 5000); if (nNewTimeout > 0 && nNewTimeout < 600000) nConnectTimeout = nNewTimeout; } // Continue to put "/P2SH/" in the coinbase to monitor // BIP16 support. // This can be removed eventually... const char* pszP2SH = "/P2SH/"; COINBASE_FLAGS << std::vector<unsigned char>(pszP2SH, pszP2SH+strlen(pszP2SH)); if (mapArgs.count("-paytxfee")) { if (!ParseMoney(mapArgs["-paytxfee"], nTransactionFee)) return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s'"), mapArgs["-paytxfee"].c_str())); if (nTransactionFee > 0.25 * COIN) InitWarning(_("Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction.")); } if (mapArgs.count("-mininput")) { if (!ParseMoney(mapArgs["-mininput"], nMinimumInputValue)) return InitError(strprintf(_("Invalid amount for -mininput=<amount>: '%s'"), mapArgs["-mininput"].c_str())); } // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log // Make sure only a single kikekoin process is using the data directory. boost::filesystem::path pathLockFile = GetDataDir() / ".lock"; FILE* file = fopen(pathLockFile.string().c_str(), "a"); // empty lock file; created if it doesn't exist. if (file) fclose(file); 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. KikeKoin is probably already running."), GetDataDir().string().c_str())); #if !defined(WIN32) && !defined(QT_GUI) if (fDaemon) { // Daemonize pid_t pid = fork(); if (pid < 0) { fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno); return false; } if (pid > 0) { CreatePidFile(GetPidFile(), pid); return true; } pid_t sid = setsid(); if (sid < 0) fprintf(stderr, "Error: setsid() returned %d errno %d\n", sid, errno); } #endif if (!fDebug) ShrinkDebugFile(); printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); printf("KikeKoin version %s (%s)\n", FormatFullVersion().c_str(), CLIENT_DATE.c_str()); printf("Startup time: %s\n", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); printf("Default data directory %s\n", GetDefaultDataDir().string().c_str()); printf("Used data directory %s\n", GetDataDir().string().c_str()); std::ostringstream strErrors; if (fDaemon) fprintf(stdout, "KikeKoin server starting\n"); int64 nStart; // ********************************************************* Step 5: network initialization int nSocksVersion = GetArg("-socks", 5); if (nSocksVersion != 4 && nSocksVersion != 5) return InitError(strprintf(_("Unknown -socks proxy version requested: %i"), nSocksVersion)); if (mapArgs.count("-onlynet")) { std::set<enum Network> nets; BOOST_FOREACH(std::string snet, mapMultiArgs["-onlynet"]) { enum Network net = ParseNetwork(snet); if (net == NET_UNROUTABLE) return InitError(strprintf(_("Unknown network specified in -onlynet: '%s'"), snet.c_str())); nets.insert(net); } for (int n = 0; n < NET_MAX; n++) { enum Network net = (enum Network)n; if (!nets.count(net)) SetLimited(net); } }
/** Initialize bitcoin. * @pre Parameters should be parsed and config file should be read. */ bool AppInit2(boost::thread_group& threadGroup) { // ********************************************************* Step 1: setup #ifdef _MSC_VER // Turn off Microsoft heap dump noise _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); #endif #if _MSC_VER >= 1400 // Disable confusing "helpful" text message on abort, Ctrl-C _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); #endif #ifdef WIN32 // Enable Data Execution Prevention (DEP) // Minimum supported OS versions: WinXP SP3, WinVista >= SP1, Win Server 2008 // A failure is non-critical and needs no further attention! #ifndef PROCESS_DEP_ENABLE // We define this here, because GCCs winbase.h limits this to _WIN32_WINNT >= 0x0601 (Windows 7), // which is not correct. Can be removed, when GCCs winbase.h is fixed! #define PROCESS_DEP_ENABLE 0x00000001 #endif typedef BOOL (WINAPI *PSETPROCDEPPOL)(DWORD); PSETPROCDEPPOL setProcDEPPol = (PSETPROCDEPPOL)GetProcAddress(GetModuleHandleA("Kernel32.dll"), "SetProcessDEPPolicy"); if (setProcDEPPol != NULL) setProcDEPPol(PROCESS_DEP_ENABLE); // Initialize Windows Sockets WSADATA wsadata; int ret = WSAStartup(MAKEWORD(2,2), &wsadata); if (ret != NO_ERROR) { return InitError(strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret)); } #endif #ifndef WIN32 umask(077); // Clean shutdown on SIGTERM struct sigaction sa; sa.sa_handler = HandleSIGTERM; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sigaction(SIGTERM, &sa, NULL); sigaction(SIGINT, &sa, NULL); // Reopen debug.log on SIGHUP struct sigaction sa_hup; sa_hup.sa_handler = HandleSIGHUP; sigemptyset(&sa_hup.sa_mask); sa_hup.sa_flags = 0; sigaction(SIGHUP, &sa_hup, NULL); #endif // ********************************************************* Step 2: parameter interactions nNodeLifespan = GetArg("-addrlifespan", 7); fUseFastIndex = GetBoolArg("-fastindex", true); nMinerSleep = GetArg("-minersleep", 500); nDerivationMethodIndex = 0; if (!SelectParamsFromCommandLine()) { return InitError("Invalid combination of -testnet and -regtest."); } if (mapArgs.count("-bind")) { // when specifying an explicit binding address, you want to listen on it // even when -connect or -proxy is specified if (SoftSetBoolArg("-listen", true)) LogPrintf("AppInit2 : parameter interaction: -bind set -> setting -listen=1\n"); } if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0) { // when only connecting to trusted nodes, do not seed via DNS, or listen by default if (SoftSetBoolArg("-dnsseed", false)) LogPrintf("AppInit2 : parameter interaction: -connect set -> setting -dnsseed=0\n"); if (SoftSetBoolArg("-listen", false)) LogPrintf("AppInit2 : parameter interaction: -connect set -> setting -listen=0\n"); } if (mapArgs.count("-proxy")) { // to protect privacy, do not listen by default if a default proxy server is specified if (SoftSetBoolArg("-listen", false)) LogPrintf("AppInit2 : parameter interaction: -proxy set -> setting -listen=0\n"); // to protect privacy, do not discover addresses by default if (SoftSetBoolArg("-discover", false)) LogPrintf("AppInit2 : parameter interaction: -proxy set -> setting -discover=0\n"); } if (!GetBoolArg("-listen", true)) { // do not map ports or try to retrieve public IP when not listening (pointless) if (SoftSetBoolArg("-upnp", false)) LogPrintf("AppInit2 : parameter interaction: -listen=0 -> setting -upnp=0\n"); if (SoftSetBoolArg("-discover", false)) LogPrintf("AppInit2 : parameter interaction: -listen=0 -> setting -discover=0\n"); } if (mapArgs.count("-externalip")) { // if an explicit public IP is specified, do not try to find others if (SoftSetBoolArg("-discover", false)) LogPrintf("AppInit2 : parameter interaction: -externalip set -> setting -discover=0\n"); } if (GetBoolArg("-salvagewallet", false)) { // Rewrite just private keys: rescan to find transactions if (SoftSetBoolArg("-rescan", true)) LogPrintf("AppInit2 : parameter interaction: -salvagewallet=1 -> setting -rescan=1\n"); } // ********************************************************* Step 3: parameter-to-internal-flags fDebug = !mapMultiArgs["-debug"].empty(); // Special-case: if -debug=0/-nodebug is set, turn off debugging messages const vector<string>& categories = mapMultiArgs["-debug"]; if (GetBoolArg("-nodebug", false) || find(categories.begin(), categories.end(), string("0")) != categories.end()) fDebug = false; // Check for -debugnet (deprecated) if (GetBoolArg("-debugnet", false)) InitWarning(_("Warning: Deprecated argument -debugnet ignored, use -debug=net")); // Check for -socks - as this is a privacy risk to continue, exit here if (mapArgs.count("-socks")) return InitError(_("Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.")); if (fDaemon) fServer = true; else fServer = GetBoolArg("-server", false); /* force fServer when running without GUI */ if (!fHaveGUI) fServer = true; fPrintToConsole = GetBoolArg("-printtoconsole", false); fLogTimestamps = GetBoolArg("-logtimestamps", false); #ifdef ENABLE_WALLET bool fDisableWallet = GetBoolArg("-disablewallet", false); #endif if (mapArgs.count("-timeout")) { int nNewTimeout = GetArg("-timeout", 5000); if (nNewTimeout > 0 && nNewTimeout < 600000) nConnectTimeout = nNewTimeout; } #ifdef ENABLE_WALLET if (mapArgs.count("-paytxfee")) { if (!ParseMoney(mapArgs["-paytxfee"], nTransactionFee)) return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s'"), mapArgs["-paytxfee"])); if (nTransactionFee > 0.25 * COIN) InitWarning(_("Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.")); } #endif fConfChange = GetBoolArg("-confchange", false); #ifdef ENABLE_WALLET if (mapArgs.count("-mininput")) { if (!ParseMoney(mapArgs["-mininput"], nMinimumInputValue)) return InitError(strprintf(_("Invalid amount for -mininput=<amount>: '%s'"), mapArgs["-mininput"])); } #endif nMaxDataCarrierBytes = GetArg("-datacarrier", nMaxDataCarrierBytes); nStakeCombineThreshold = GetArg("-stakecombine", nStakeCombineThreshold * COIN); // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log // Sanity check if (!InitSanityCheck()) return InitError(_("Initialization sanity check failed. Rubycoin is shutting down.")); std::string strDataDir = GetDataDir().string(); #ifdef ENABLE_WALLET std::string strWalletFileName = GetArg("-wallet", "wallet.dat"); // strWalletFileName must be a plain filename without a directory if (strWalletFileName != boost::filesystem::basename(strWalletFileName) + boost::filesystem::extension(strWalletFileName)) return InitError(strprintf(_("Wallet %s resides outside data directory %s."), strWalletFileName, strDataDir)); #endif // Make sure only a single Bitcoin process is using the data directory. boost::filesystem::path pathLockFile = GetDataDir() / ".lock"; FILE* file = fopen(pathLockFile.string().c_str(), "a"); // empty lock file; created if it doesn't exist. if (file) fclose(file); 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. Rubycoin is probably already running."), strDataDir)); 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("Rubycoin version %s (%s)\n", FormatFullVersion(), CLIENT_DATE); LogPrintf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION)); if (!fLogTimestamps) LogPrintf("Startup time: %s\n", DateTimeStrFormat("%x %H:%M:%S", GetTime())); LogPrintf("Default data directory %s\n", GetDefaultDataDir().string()); LogPrintf("Used data directory %s\n", strDataDir); std::ostringstream strErrors; if (fDaemon) fprintf(stdout, "Rubycoin server starting\n"); int64_t nStart; // ********************************************************* Step 5: verify database integrity #ifdef ENABLE_WALLET if (!fDisableWallet) { uiInterface.InitMessage(_("Verifying database integrity...")); if (!bitdb.Open(GetDataDir())) { // try moving the database env out of the way boost::filesystem::path pathDatabase = GetDataDir() / "database"; boost::filesystem::path pathDatabaseBak = GetDataDir() / strprintf("database.%d.bak", GetTime()); try { boost::filesystem::rename(pathDatabase, pathDatabaseBak); LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string(), pathDatabaseBak.string()); } catch(boost::filesystem::filesystem_error &error) { // failure is ok (well, not really, but it's not worse than what we started with) } // try again if (!bitdb.Open(GetDataDir())) { // if it still fails, it probably means we can't even create the database env string msg = strprintf(_("Error initializing wallet database environment %s!"), strDataDir); return InitError(msg); } } if (GetBoolArg("-salvagewallet", false)) { // Recover readable keypairs: if (!CWalletDB::Recover(bitdb, strWalletFileName, true)) return false; } if (filesystem::exists(GetDataDir() / strWalletFileName)) { CDBEnv::VerifyResult r = bitdb.Verify(strWalletFileName, CWalletDB::Recover); if (r == CDBEnv::RECOVER_OK) { string msg = strprintf(_("Warning: wallet.dat corrupt, data salvaged!" " Original wallet.dat saved as wallet.{timestamp}.bak in %s; if" " your balance or transactions are incorrect you should" " restore from a backup."), strDataDir); InitWarning(msg); } if (r == CDBEnv::RECOVER_FAIL) return InitError(_("wallet.dat corrupt, salvage failed")); } } // (!fDisableWallet) #endif // ENABLE_WALLET // ********************************************************* Step 6: network initialization RegisterNodeSignals(GetNodeSignals()); if (mapArgs.count("-onlynet")) { std::set<enum Network> nets; BOOST_FOREACH(std::string snet, mapMultiArgs["-onlynet"]) { enum Network net = ParseNetwork(snet); if (net == NET_UNROUTABLE) return InitError(strprintf(_("Unknown network specified in -onlynet: '%s'"), snet)); nets.insert(net); } for (int n = 0; n < NET_MAX; n++) { enum Network net = (enum Network)n; if (!nets.count(net)) SetLimited(net); } }
/** Initialize Gridcoin. * @pre Parameters should be parsed and config file should be read. */ bool AppInit2(ThreadHandlerPtr threads) { // ********************************************************* Step 1: setup #ifdef _MSC_VER // Turn off Microsoft heap dump noise _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); #endif #if _MSC_VER >= 1400 // Disable confusing "helpful" text message on abort, Ctrl-C _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); #endif #ifdef WIN32 // Enable Data Execution Prevention (DEP) // Minimum supported OS versions: WinXP SP3, WinVista >= SP1, Win Server 2008 // A failure is non-critical and needs no further attention! #ifndef PROCESS_DEP_ENABLE // We define this here, because GCCs winbase.h limits this to _WIN32_WINNT >= 0x0601 (Windows 7), // which is not correct. Can be removed, when GCCs winbase.h is fixed! #define PROCESS_DEP_ENABLE 0x00000001 #endif typedef BOOL (WINAPI *PSETPROCDEPPOL)(DWORD); PSETPROCDEPPOL setProcDEPPol = (PSETPROCDEPPOL)GetProcAddress(GetModuleHandleA("Kernel32.dll"), "SetProcessDEPPolicy"); if (setProcDEPPol != NULL) setProcDEPPol(PROCESS_DEP_ENABLE); #endif #ifndef WIN32 umask(077); // Clean shutdown on SIGTERM struct sigaction sa; sa.sa_handler = HandleSIGTERM; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sigaction(SIGTERM, &sa, NULL); sigaction(SIGINT, &sa, NULL); // Reopen debug.log on SIGHUP struct sigaction sa_hup; sa_hup.sa_handler = HandleSIGHUP; sigemptyset(&sa_hup.sa_mask); sa_hup.sa_flags = 0; sigaction(SIGHUP, &sa_hup, NULL); #endif // ********************************************************* Step 2: parameter interactions // Gridcoin - Check to see if config is empty? if (IsConfigFileEmpty()) { uiInterface.ThreadSafeMessageBox( "Configuration file empty. \n" + _("Please wait for new user wizard to start..."), "", 0); } //6-10-2014: R Halford: Updating Boost version to 1.5.5 to prevent sync issues; print the boost version to verify: //5-04-2018: J Owens: Boost now needs to be 1.65 or higher to avoid thread sleep problems with system clock resets. std::string boost_version = ""; std::ostringstream s; s << boost_version << "Using Boost " << BOOST_VERSION / 100000 << "." // major version << BOOST_VERSION / 100 % 1000 << "." // minior version << BOOST_VERSION % 100 // patch level << "\n"; LogPrintf("Boost Version: %s", s.str()); //Placeholder: Load Remote CPIDs Here nNodeLifespan = GetArg("-addrlifespan", 7); fUseFastIndex = GetBoolArg("-fastindex", false); nMinerSleep = GetArg("-minersleep", 8000); nDerivationMethodIndex = 0; fTestNet = GetBoolArg("-testnet"); if (mapArgs.count("-bind")) { // when specifying an explicit binding address, you want to listen on it // even when -connect or -proxy is specified SoftSetBoolArg("-listen", true); } if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0) { // when only connecting to trusted nodes, do not seed via DNS, or listen by default SoftSetBoolArg("-dnsseed", false); SoftSetBoolArg("-listen", false); } if (mapArgs.count("-proxy")) { // to protect privacy, do not listen by default if a proxy server is specified SoftSetBoolArg("-listen", false); } if (!GetBoolArg("-listen", true)) { // do not map ports or try to retrieve public IP when not listening (pointless) SoftSetBoolArg("-upnp", false); SoftSetBoolArg("-discover", false); } if (mapArgs.count("-externalip")) { // if an explicit public IP is specified, do not try to find others SoftSetBoolArg("-discover", false); } if (GetBoolArg("-salvagewallet")) { // Rewrite just private keys: rescan to find transactions SoftSetBoolArg("-rescan", true); } if (GetBoolArg("-zapwallettxes", false)) { // -zapwallettx implies a rescan SoftSetBoolArg("-rescan", true); } // Verify testnet is using the testnet directory for the config file: std::string sTestNetSpecificArg = GetArgument("testnetarg","default"); LogPrintf("Using specific arg %s",sTestNetSpecificArg); // ********************************************************* Step 3: parameter-to-internal-flags fDebug=false; if (fDebug) fDebugNet = true; else fDebugNet = GetBoolArg("-debugnet"); if (GetArg("-debug", "false")=="true") { fDebug = true; LogPrintf("Entering debug mode."); } fDebug2 = false; if (GetArg("-debug2", "false")=="true") { fDebug2 = true; LogPrintf("Entering GRC debug mode 2."); } fDebug3 = false; if (GetArg("-debug3", "false")=="true") { fDebug3 = true; LogPrintf("Entering GRC debug mode 3."); } if (GetArg("-debug4", "false")=="true") { fDebug4 = true; LogPrintf("Entering RPC time debug mode"); } fDebug10= (GetArg("-debug10","false")=="true"); #if defined(WIN32) fDaemon = false; #else if(fQtActive) fDaemon = false; else fDaemon = GetBoolArg("-daemon"); #endif if (fDaemon) fServer = true; else fServer = GetBoolArg("-server"); /* force fServer when running without GUI */ if(!fQtActive) fServer = true; fPrintToConsole = GetBoolArg("-printtoconsole"); fPrintToDebugger = GetBoolArg("-printtodebugger"); fLogTimestamps = GetBoolArg("-logtimestamps"); fLogTimestamps = true; if (mapArgs.count("-timeout")) { int nNewTimeout = GetArg("-timeout", 4000); if (nNewTimeout > 0 && nNewTimeout < 600000) nConnectTimeout = nNewTimeout; } if (mapArgs.count("-paytxfee")) { if (!ParseMoney(mapArgs["-paytxfee"], nTransactionFee)) return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s'"), mapArgs["-paytxfee"])); if (nTransactionFee > 0.25 * COIN) InitWarning(_("Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.")); } fConfChange = GetBoolArg("-confchange", false); fEnforceCanonical = GetBoolArg("-enforcecanonical", true); if (mapArgs.count("-mininput")) { if (!ParseMoney(mapArgs["-mininput"], nMinimumInputValue)) return InitError(strprintf(_("Invalid amount for -mininput=<amount>: '%s'"), mapArgs["-mininput"])); } // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log // Sanity check if (!InitSanityCheck()) return InitError(_("Initialization sanity check failed. Gridcoin is shutting down.")); // Initialize internal hashing code with SSE/AVX2 optimizations. In the future we will also have ARM/NEON optimizations. std::string sha256_algo = SHA256AutoDetect(); LogPrintf("Using the '%s' SHA256 implementation\n", sha256_algo); std::string strDataDir = GetDataDir().string(); std::string strWalletFileName = GetArg("-wallet", "wallet.dat"); // strWalletFileName must be a plain filename without a directory if (strWalletFileName != boost::filesystem::basename(strWalletFileName) + boost::filesystem::extension(strWalletFileName)) return InitError(strprintf(_("Wallet %s resides outside data directory %s."), strWalletFileName, strDataDir)); // Make sure only a single Bitcoin process is using the data directory. boost::filesystem::path pathLockFile = GetDataDir() / ".lock"; FILE* file = fopen(pathLockFile.string().c_str(), "a"); // empty lock file; created if it doesn't exist. if (file) fclose(file); 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. Gridcoin is probably already running."), strDataDir)); #if !defined(WIN32) if (fDaemon) { // Daemonize pid_t pid = fork(); if (pid < 0) { fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno); return false; } if (pid > 0) { CreatePidFile(GetPidFile(), pid); // Now that we are forked we can request a shutdown so the parent // exits while the child lives on. StartShutdown(); return true; } pid_t sid = setsid(); if (sid < 0) fprintf(stderr, "Error: setsid() returned %d errno %d\n", sid, errno); } #endif ShrinkDebugFile(); LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); LogPrintf("Gridcoin version %s (%s)", FormatFullVersion(), CLIENT_DATE); LogPrintf("Using OpenSSL version %s", SSLeay_version(SSLEAY_VERSION)); if (!fLogTimestamps) LogPrintf("Startup time: %s", DateTimeStrFormat("%x %H:%M:%S", GetAdjustedTime())); LogPrintf("Default data directory %s", GetDefaultDataDir().string()); LogPrintf("Used data directory %s", strDataDir); std::ostringstream strErrors; fDevbuildCripple = false; if((CLIENT_VERSION_BUILD != 0) && !fTestNet) { fDevbuildCripple = true; LogPrintf("WARNING: Running development version outside of testnet!\n" "Staking and sending transactions will be disabled."); if( (GetArg("-devbuild", "") == "override") && fDebug ) fDevbuildCripple = false; } if (fDaemon) fprintf(stdout, "Gridcoin server starting\n"); int64_t nStart; // ********************************************************* Step 5: verify database integrity uiInterface.InitMessage(_("Verifying database integrity...")); if (!bitdb.Open(GetDataDir())) { string msg = strprintf(_("Error initializing database environment %s!" " To recover, BACKUP THAT DIRECTORY, then remove" " everything from it except for wallet.dat."), strDataDir); return InitError(msg); } if (GetBoolArg("-salvagewallet")) { // Recover readable keypairs: if (!CWalletDB::Recover(bitdb, strWalletFileName, true)) return false; } if (filesystem::exists(GetDataDir() / strWalletFileName)) { CDBEnv::VerifyResult r = bitdb.Verify(strWalletFileName, CWalletDB::Recover); if (r == CDBEnv::RECOVER_OK) { string msg = strprintf(_("Warning: wallet.dat corrupt, data salvaged!" " Original wallet.dat saved as wallet.{timestamp}.bak in %s; if" " your balance or transactions are incorrect you should" " restore from a backup."), strDataDir); uiInterface.ThreadSafeMessageBox(msg, _("Gridcoin"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL); } if (r == CDBEnv::RECOVER_FAIL) return InitError(_("wallet.dat corrupt, salvage failed")); } // ********************************************************* Step 6: network initialization int nSocksVersion = GetArg("-socks", 5); if (nSocksVersion != 4 && nSocksVersion != 5) return InitError(strprintf(_("Unknown -socks proxy version requested: %i"), nSocksVersion)); if (mapArgs.count("-onlynet")) { std::set<enum Network> nets; for (auto const& snet : mapMultiArgs["-onlynet"]) { enum Network net = ParseNetwork(snet); if (net == NET_UNROUTABLE) return InitError(strprintf(_("Unknown network specified in -onlynet: '%s'"), snet)); nets.insert(net); } for (int n = 0; n < NET_MAX; n++) { enum Network net = (enum Network)n; if (!nets.count(net)) SetLimited(net); } } CService addrProxy; bool fProxy = false; if (mapArgs.count("-proxy")) { addrProxy = CService(mapArgs["-proxy"], 9050); if (!addrProxy.IsValid()) return InitError(strprintf(_("Invalid -proxy address: '%s'"), mapArgs["-proxy"])); if (!IsLimited(NET_IPV4)) SetProxy(NET_IPV4, addrProxy, nSocksVersion); if (nSocksVersion > 4) { if (!IsLimited(NET_IPV6)) SetProxy(NET_IPV6, addrProxy, nSocksVersion); SetNameProxy(addrProxy, nSocksVersion); } fProxy = true; } // -tor can override normal proxy, -notor disables tor entirely if (!(mapArgs.count("-tor") && mapArgs["-tor"] == "0") && (fProxy || mapArgs.count("-tor"))) { CService addrOnion; if (!mapArgs.count("-tor")) addrOnion = addrProxy; else addrOnion = CService(mapArgs["-tor"], 9050); if (!addrOnion.IsValid()) return InitError(strprintf(_("Invalid -tor address: '%s'"), mapArgs["-tor"])); SetProxy(NET_TOR, addrOnion, 5); SetReachable(NET_TOR); } // see Step 2: parameter interactions for more information about these fNoListen = !GetBoolArg("-listen", true); fDiscover = GetBoolArg("-discover", true); fNameLookup = GetBoolArg("-dns", true); #ifdef USE_UPNP fUseUPnP = GetBoolArg("-upnp", USE_UPNP); #endif bool fBound = false; if (!fNoListen) { std::string strError; if (mapArgs.count("-bind")) { for (auto const& 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); } } else { struct in_addr inaddr_any; inaddr_any.s_addr = INADDR_ANY; if (!IsLimited(NET_IPV6)) fBound |= Bind(CService(in6addr_any, GetListenPort()), false); if (!IsLimited(NET_IPV4)) fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound); } if (!fBound) return InitError(_("Failed to listen on any port. Use -listen=0 if you want this.")); } if (mapArgs.count("-externalip")) { for (auto const& strAddr : mapMultiArgs["-externalip"]) { CService addrLocal(strAddr, GetListenPort(), fNameLookup); if (!addrLocal.IsValid()) return InitError(strprintf(_("Cannot resolve -externalip address: '%s'"), strAddr)); AddLocal(CService(strAddr, GetListenPort(), fNameLookup), LOCAL_MANUAL); } } if (mapArgs.count("-reservebalance")) // ppcoin: reserve balance amount { if (!ParseMoney(mapArgs["-reservebalance"], nReserveBalance)) { InitError(_("Invalid amount for -reservebalance=<amount>")); return false; } } for (auto const& strDest : mapMultiArgs["-seednode"]) AddOneShot(strDest); // ********************************************************* Step 7: load blockchain if (!bitdb.Open(GetDataDir())) { string msg = strprintf(_("Error initializing database environment %s!" " To recover, BACKUP THAT DIRECTORY, then remove" " everything from it except for wallet.dat."), strDataDir); return InitError(msg); } if (GetBoolArg("-loadblockindextest")) { CTxDB txdb("r"); txdb.LoadBlockIndex(); PrintBlockTree(); return false; } uiInterface.InitMessage(_("Loading block index...")); LogPrintf("Loading block index..."); nStart = GetTimeMillis(); if (!LoadBlockIndex()) return InitError(_("Error loading blkindex.dat")); // as LoadBlockIndex can take several minutes, it's possible the user // requested to kill bitcoin-qt during the last operation. If so, exit. // As the program has not fully started yet, Shutdown() is possibly overkill. if (fRequestShutdown) { LogPrintf("Shutdown requested. Exiting."); return false; } LogPrintf(" block index %15" PRId64 "ms", GetTimeMillis() - nStart); if (GetBoolArg("-printblockindex") || GetBoolArg("-printblocktree")) { PrintBlockTree(); return false; } if (mapArgs.count("-printblock")) { string strMatch = mapArgs["-printblock"]; int nFound = 0; for (BlockMap::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi) { uint256 hash = (*mi).first; if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0) { CBlockIndex* pindex = (*mi).second; CBlock block; block.ReadFromDisk(pindex); block.BuildMerkleTree(); block.print(); LogPrintf(""); nFound++; } } if (nFound == 0) LogPrintf("No blocks matching %s were found", strMatch); return false; } // ********************************************************* Step 8: load wallet uiInterface.InitMessage(_("Loading wallet...")); LogPrintf("Loading wallet..."); nStart = GetTimeMillis(); bool fFirstRun = true; pwalletMain = new CWallet(strWalletFileName); DBErrors nLoadWalletRet = pwalletMain->LoadWallet(fFirstRun); if (nLoadWalletRet != DB_LOAD_OK) { if (nLoadWalletRet == DB_CORRUPT) strErrors << _("Error loading wallet.dat: Wallet corrupted") << "\n"; else if (nLoadWalletRet == DB_NONCRITICAL_ERROR) { string msg(_("Warning: error reading wallet.dat! All keys read correctly, but transaction data" " or address book entries might be missing or incorrect.")); uiInterface.ThreadSafeMessageBox(msg, _("Gridcoin"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL); } else if (nLoadWalletRet == DB_TOO_NEW) strErrors << _("Error loading wallet.dat: Wallet requires newer version of Gridcoin") << "\n"; else if (nLoadWalletRet == DB_NEED_REWRITE) { strErrors << _("Wallet needed to be rewritten: restart Gridcoin to complete") << "\n"; LogPrintf("%s", strErrors.str()); return InitError(strErrors.str()); } else strErrors << _("Error loading wallet.dat") << "\n"; } if (GetBoolArg("-upgradewallet", fFirstRun)) { int nMaxVersion = GetArg("-upgradewallet", 0); if (nMaxVersion == 0) // the -upgradewallet without argument case { LogPrintf("Performing wallet upgrade to %i", FEATURE_LATEST); nMaxVersion = CLIENT_VERSION; pwalletMain->SetMinVersion(FEATURE_LATEST); // permanently upgrade the wallet immediately } else LogPrintf("Allowing wallet upgrade up to %i", nMaxVersion); if (nMaxVersion < pwalletMain->GetVersion()) strErrors << _("Cannot downgrade wallet") << "\n"; pwalletMain->SetMaxVersion(nMaxVersion); } if (fFirstRun) { // Create new keyUser and set as default key RandAddSeedPerfmon(); CPubKey newDefaultKey; if (pwalletMain->GetKeyFromPool(newDefaultKey, false)) { pwalletMain->SetDefaultKey(newDefaultKey); if (!pwalletMain->SetAddressBookName(pwalletMain->vchDefaultKey.GetID(), "")) strErrors << _("Cannot write default address") << "\n"; } } LogPrintf("%s", strErrors.str()); LogPrintf(" wallet %15" PRId64 "ms", GetTimeMillis() - nStart); RegisterWallet(pwalletMain); CBlockIndex *pindexRescan = pindexBest; if (GetBoolArg("-rescan")) pindexRescan = pindexGenesisBlock; else { CWalletDB walletdb(strWalletFileName); CBlockLocator locator; if (walletdb.ReadBestBlock(locator)) pindexRescan = locator.GetBlockIndex(); } if (pindexBest != pindexRescan && pindexBest && pindexRescan && pindexBest->nHeight > pindexRescan->nHeight) { uiInterface.InitMessage(_("Rescanning...")); LogPrintf("Rescanning last %i blocks (from block %i)...", pindexBest->nHeight - pindexRescan->nHeight, pindexRescan->nHeight); nStart = GetTimeMillis(); pwalletMain->ScanForWalletTransactions(pindexRescan, true); LogPrintf(" rescan %15" PRId64 "ms", GetTimeMillis() - nStart); } // ********************************************************* Step 9: import blocks if (mapArgs.count("-loadblock")) { uiInterface.InitMessage(_("Importing blockchain data file.")); for (auto const& strFile : mapMultiArgs["-loadblock"]) { FILE *file = fopen(strFile.c_str(), "rb"); if (file) LoadExternalBlockFile(file); } exit(0); } filesystem::path pathBootstrap = GetDataDir() / "bootstrap.dat"; if (filesystem::exists(pathBootstrap)) { uiInterface.InitMessage(_("Importing bootstrap blockchain data file.")); FILE *file = fopen(pathBootstrap.string().c_str(), "rb"); if (file) { filesystem::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old"; LoadExternalBlockFile(file); RenameOver(pathBootstrap, pathBootstrapOld); } } // ********************************************************* Step 10: load peers uiInterface.InitMessage(_("Loading addresses...")); if (fDebug10) LogPrintf("Loading addresses..."); nStart = GetTimeMillis(); { CAddrDB adb; if (!adb.Read(addrman)) LogPrintf("Invalid or missing peers.dat; recreating"); } LogPrintf("Loaded %i addresses from peers.dat %" PRId64 "ms", addrman.size(), GetTimeMillis() - nStart); // ********************************************************* Step 11: start node uiInterface.InitMessage(_("Loading Persisted Data Cache...")); // std::string sOut = ""; if (fDebug3) LogPrintf("Loading admin Messages"); LoadAdminMessages(true,sOut); LogPrintf("Done loading Admin messages"); uiInterface.InitMessage(_("Compute Neural Network Hashes...")); ComputeNeuralNetworkSupermajorityHashes(); LoadCPIDs(); uiInterface.InitMessage(_("Finding first applicable Research Project...")); if (!CheckDiskSpace()) return false; RandAddSeedPerfmon(); //// debug print if (fDebug) { LogPrintf("mapBlockIndex.size() = %" PRIszu, mapBlockIndex.size()); LogPrintf("nBestHeight = %d", nBestHeight); LogPrintf("setKeyPool.size() = %" PRIszu, pwalletMain->setKeyPool.size()); LogPrintf("mapWallet.size() = %" PRIszu, pwalletMain->mapWallet.size()); LogPrintf("mapAddressBook.size() = %" PRIszu, pwalletMain->mapAddressBook.size()); } uiInterface.InitMessage(_("Loading Network Averages...")); if (fDebug3) LogPrintf("Loading network averages"); CBlockIndex* tallyHeight = FindTallyTrigger(pindexBest); if(tallyHeight) TallyResearchAverages(tallyHeight); if (!threads->createThread(StartNode, NULL, "Start Thread")) InitError(_("Error: could not start node")); if (fServer) StartRPCThreads(); // ********************************************************* Step 12: finished uiInterface.InitMessage(_("Done loading")); LogPrintf("Done loading"); if (!strErrors.str().empty()) return InitError(strErrors.str()); // Add wallet transactions that aren't already in a block to mapTransactions pwalletMain->ReacceptWalletTransactions(); int nMismatchSpent; int64_t nBalanceInQuestion; pwalletMain->FixSpentCoins(nMismatchSpent, nBalanceInQuestion); return true; }
/** Initialize bitcoin. * @pre Parameters should be parsed and config file should be read. */ bool AppInit2() { // ********************************************************* Step 1: setup #ifdef _MSC_VER // Turn off Microsoft heap dump noise _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); #endif #if _MSC_VER >= 1400 // Disable confusing "helpful" text message on abort, Ctrl-C _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); #endif #ifdef WIN32 // Enable Data Execution Prevention (DEP) // Minimum supported OS versions: WinXP SP3, WinVista >= SP1, Win Server 2008 // A failure is non-critical and needs no further attention! #ifndef PROCESS_DEP_ENABLE // We define this here, because GCCs winbase.h limits this to _WIN32_WINNT >= 0x0601 (Windows 7), // which is not correct. Can be removed, when GCCs winbase.h is fixed! #define PROCESS_DEP_ENABLE 0x00000001 #endif typedef BOOL (WINAPI *PSETPROCDEPPOL)(DWORD); PSETPROCDEPPOL setProcDEPPol = (PSETPROCDEPPOL)GetProcAddress(GetModuleHandleA("Kernel32.dll"), "SetProcessDEPPolicy"); if (setProcDEPPol != NULL) setProcDEPPol(PROCESS_DEP_ENABLE); #endif #ifndef WIN32 umask(077); // Clean shutdown on SIGTERM struct sigaction sa; sa.sa_handler = HandleSIGTERM; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sigaction(SIGTERM, &sa, NULL); sigaction(SIGINT, &sa, NULL); // Reopen debug.log on SIGHUP struct sigaction sa_hup; sa_hup.sa_handler = HandleSIGHUP; sigemptyset(&sa_hup.sa_mask); sa_hup.sa_flags = 0; sigaction(SIGHUP, &sa_hup, NULL); #endif // ********************************************************* Step 2: parameter interactions fTestNet = GetBoolArg("-testnet"); if (fTestNet) { SoftSetBoolArg("-irc", true); } if (mapArgs.count("-bind")) { // when specifying an explicit binding address, you want to listen on it // even when -connect or -proxy is specified SoftSetBoolArg("-listen", true); } if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0) { // when only connecting to trusted nodes, do not seed via DNS, or listen by default SoftSetBoolArg("-dnsseed", false); SoftSetBoolArg("-listen", false); } if (mapArgs.count("-proxy")) { // to protect privacy, do not listen by default if a proxy server is specified SoftSetBoolArg("-listen", false); } if (!GetBoolArg("-listen", true)) { // do not map ports or try to retrieve public IP when not listening (pointless) SoftSetBoolArg("-upnp", false); SoftSetBoolArg("-discover", false); } if (mapArgs.count("-externalip")) { // if an explicit public IP is specified, do not try to find others SoftSetBoolArg("-discover", false); } if (GetBoolArg("-salvagewallet")) { // Rewrite just private keys: rescan to find transactions SoftSetBoolArg("-rescan", true); } // ********************************************************* Step 3: parameter-to-internal-flags fDebug = GetBoolArg("-debug"); // -debug implies fDebug* if (fDebug) fDebugNet = true; else fDebugNet = GetBoolArg("-debugnet"); bitdb.SetDetach(GetBoolArg("-detachdb", false)); #if !defined(WIN32) && !defined(QT_GUI) fDaemon = GetBoolArg("-daemon"); #else fDaemon = false; #endif if (fDaemon) fServer = true; else fServer = GetBoolArg("-server"); /* force fServer when running without GUI */ #if !defined(QT_GUI) fServer = true; #endif fPrintToConsole = GetBoolArg("-printtoconsole"); fPrintToDebugger = GetBoolArg("-printtodebugger"); fLogTimestamps = GetBoolArg("-logtimestamps"); if (mapArgs.count("-timeout")) { int nNewTimeout = GetArg("-timeout", 5000); if (nNewTimeout > 0 && nNewTimeout < 600000) nConnectTimeout = nNewTimeout; } // Continue to put "/P2SH/" in the coinbase to monitor // BIP16 support. // This can be removed eventually... const char* pszP2SH = "/P2SH/"; COINBASE_FLAGS << std::vector<unsigned char>(pszP2SH, pszP2SH+strlen(pszP2SH)); if (mapArgs.count("-paytxfee")) { if (!ParseMoney(mapArgs["-paytxfee"], nTransactionFee)) return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s'"), mapArgs["-paytxfee"].c_str())); if (nTransactionFee > 0.25 * COIN) InitWarning(_("Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.")); } // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log std::string strDataDir = GetDataDir().string(); // Make sure only a single Bitcoin process is using the data directory. boost::filesystem::path pathLockFile = GetDataDir() / ".lock"; FILE* file = fopen(pathLockFile.string().c_str(), "a"); // empty lock file; created if it doesn't exist. if (file) fclose(file); 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. NovaCoin is probably already running."), strDataDir.c_str())); #if !defined(WIN32) && !defined(QT_GUI) if (fDaemon) { // Daemonize pid_t pid = fork(); if (pid < 0) { fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno); return false; } if (pid > 0) { CreatePidFile(GetPidFile(), pid); return true; } pid_t sid = setsid(); if (sid < 0) fprintf(stderr, "Error: setsid() returned %d errno %d\n", sid, errno); } #endif if (GetBoolArg("-shrinkdebugfile", !fDebug)) ShrinkDebugFile(); printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); printf("Webcoin version %s (%s)\n", FormatFullVersion().c_str(), CLIENT_DATE.c_str()); printf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION)); if (!fLogTimestamps) printf("Startup time: %s\n", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); printf("Default data directory %s\n", GetDefaultDataDir().string().c_str()); printf("Used data directory %s\n", strDataDir.c_str()); std::ostringstream strErrors; if (fDaemon) fprintf(stdout, "Webcoin server starting\n"); int64 nStart; // ********************************************************* Step 5: verify database integrity uiInterface.InitMessage(_("Verifying database integrity...")); if (!bitdb.Open(GetDataDir())) { string msg = strprintf(_("Error initializing database environment %s!" " To recover, BACKUP THAT DIRECTORY, then remove" " everything from it except for wallet.dat."), strDataDir.c_str()); return InitError(msg); } if (GetBoolArg("-salvagewallet")) { // Recover readable keypairs: if (!CWalletDB::Recover(bitdb, "wallet.dat", true)) return false; } if (filesystem::exists(GetDataDir() / "wallet.dat")) { CDBEnv::VerifyResult r = bitdb.Verify("wallet.dat", CWalletDB::Recover); if (r == CDBEnv::RECOVER_OK) { string msg = strprintf(_("Warning: wallet.dat corrupt, data salvaged!" " Original wallet.dat saved as wallet.{timestamp}.bak in %s; if" " your balance or transactions are incorrect you should" " restore from a backup."), strDataDir.c_str()); uiInterface.ThreadSafeMessageBox(msg, _("Webcoin"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL); } if (r == CDBEnv::RECOVER_FAIL) return InitError(_("wallet.dat corrupt, salvage failed")); } // ********************************************************* Step 6: network initialization int nSocksVersion = GetArg("-socks", 5); if (nSocksVersion != 4 && nSocksVersion != 5) return InitError(strprintf(_("Unknown -socks proxy version requested: %i"), nSocksVersion)); if (mapArgs.count("-onlynet")) { std::set<enum Network> nets; BOOST_FOREACH(std::string snet, mapMultiArgs["-onlynet"]) { enum Network net = ParseNetwork(snet); if (net == NET_UNROUTABLE) return InitError(strprintf(_("Unknown network specified in -onlynet: '%s'"), snet.c_str())); nets.insert(net); } for (int n = 0; n < NET_MAX; n++) { enum Network net = (enum Network)n; if (!nets.count(net)) SetLimited(net); } }
/** Initialize bitcoin. * @pre Parameters should be parsed and config file should be read. */ bool AppInit2(boost::thread_group& threadGroup) { // ********************************************************* Step 1: setup #ifdef _MSC_VER // Turn off Microsoft heap dump noise _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); #endif #if _MSC_VER >= 1400 // Disable confusing "helpful" text message on abort, Ctrl-C _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); #endif #ifdef WIN32 // Enable Data Execution Prevention (DEP) // Minimum supported OS versions: WinXP SP3, WinVista >= SP1, Win Server 2008 // A failure is non-critical and needs no further attention! #ifndef PROCESS_DEP_ENABLE // We define this here, because GCCs winbase.h limits this to _WIN32_WINNT >= 0x0601 (Windows 7), // which is not correct. Can be removed, when GCCs winbase.h is fixed! #define PROCESS_DEP_ENABLE 0x00000001 #endif typedef BOOL (WINAPI *PSETPROCDEPPOL)(DWORD); PSETPROCDEPPOL setProcDEPPol = (PSETPROCDEPPOL)GetProcAddress(GetModuleHandleA("Kernel32.dll"), "SetProcessDEPPolicy"); if (setProcDEPPol != NULL) setProcDEPPol(PROCESS_DEP_ENABLE); #endif #ifndef WIN32 umask(077); // Clean shutdown on SIGTERM struct sigaction sa; sa.sa_handler = HandleSIGTERM; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sigaction(SIGTERM, &sa, NULL); sigaction(SIGINT, &sa, NULL); // Reopen debug.log on SIGHUP struct sigaction sa_hup; sa_hup.sa_handler = HandleSIGHUP; sigemptyset(&sa_hup.sa_mask); sa_hup.sa_flags = 0; sigaction(SIGHUP, &sa_hup, NULL); #endif if (!CheckDiskSpace()) return false; // ********************************************************* Step 2: parameter interactions nNodeLifespan = GetArg("-addrlifespan", 7); nMinStakeInterval = GetArg("-minstakeinterval", 0); nMinerSleep = GetArg("-minersleep", 500); // Largest block you're willing to create. // Limit to betweeen 1K and MAX_BLOCK_SIZE-1K for sanity: nBlockMaxSize = GetArg("-blockmaxsize", MAX_BLOCK_SIZE_GEN/2); nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SIZE-1000), nBlockMaxSize)); // How much of the block should be dedicated to high-priority transactions, // included regardless of the fees they pay nBlockPrioritySize = GetArg("-blockprioritysize", 27000); nBlockPrioritySize = std::min(nBlockMaxSize, nBlockPrioritySize); // Minimum block size you want to create; block will be filled with free transactions // until there are no more or the block reaches this size: nBlockMinSize = GetArg("-blockminsize", 0); nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize); // Fee-per-kilobyte amount considered the same as "free" // Be careful setting this: if you set it to zero then // a transaction spammer can cheaply fill blocks using // 1-satoshi-fee transactions. It should be set above the real // cost to you of processing a transaction. if (mapArgs.count("-mintxfee")) ParseMoney(mapArgs["-mintxfee"], nMinTxFee); if (fDebug) LogPrintf("nMinerSleep %u\n", nMinerSleep); CheckpointsMode = Checkpoints::STRICT; std::string strCpMode = GetArg("-cppolicy", "strict"); if (strCpMode == "strict") CheckpointsMode = Checkpoints::STRICT; if (strCpMode == "advisory") CheckpointsMode = Checkpoints::ADVISORY; if (strCpMode == "permissive") CheckpointsMode = Checkpoints::PERMISSIVE; nDerivationMethodIndex = 0; fTestNet = GetBoolArg("-testnet"); if (!SelectParamsFromCommandLine()) return InitError("Invalid combination of -testnet and -regtest."); if (GetBoolArg("-thinmode")) nNodeMode = NT_THIN; if (fTestNet) { SoftSetBoolArg("-irc", true); } if (mapArgs.count("-bind")) { // when specifying an explicit binding address, you want to listen on it // even when -connect or -proxy is specified SoftSetBoolArg("-listen", true); } if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0) { // when only connecting to trusted nodes, do not seed via DNS, or listen by default SoftSetBoolArg("-dnsseed", false); SoftSetBoolArg("-listen", false); } if (mapArgs.count("-proxy")) { // to protect privacy, do not listen by default if a proxy server is specified SoftSetBoolArg("-listen", false); } if (!GetBoolArg("-listen", true)) { // do not map ports or try to retrieve public IP when not listening (pointless) SoftSetBoolArg("-upnp", false); SoftSetBoolArg("-discover", false); } if (mapArgs.count("-externalip")) { // if an explicit public IP is specified, do not try to find others SoftSetBoolArg("-discover", false); } if (GetBoolArg("-salvagewallet")) { // Rewrite just private keys: rescan to find transactions SoftSetBoolArg("-rescan", true); } if (fTestNet) { nStakeMinAge = 1 * 60 * 60; // test net min age is 1 hour nCoinbaseMaturity = 10; // test maturity is 10 blocks }; // ********************************************************* Step 3: parameter-to-internal-flags fDebug = !mapMultiArgs["-debug"].empty(); // Special-case: if -debug=0/-nodebug is set, turn off debugging messages const std::vector<std::string>& categories = mapMultiArgs["-debug"]; if (GetBoolArg("-nodebug", false) || std::find(categories.begin(), categories.end(), std::string("0")) != categories.end()) fDebug = false; // -debug implies fDebug*, unless otherwise specified if (fDebug) { SoftSetBoolArg("-debugnet", true); SoftSetBoolArg("-debugsmsg", true); SoftSetBoolArg("-debugchain", true); SoftSetBoolArg("-debugringsig", true); }; fDebugNet = GetBoolArg("-debugnet"); fDebugSmsg = GetBoolArg("-debugsmsg"); fDebugChain = GetBoolArg("-debugchain"); fDebugRingSig = GetBoolArg("-debugringsig"); fDebugPoS = GetBoolArg("-debugpos"); fNoSmsg = GetBoolArg("-nosmsg"); // Check for -socks - as this is a privacy risk to continue, exit here if (mapArgs.count("-socks")) return InitError(_("Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.")); bitdb.SetDetach(GetBoolArg("-detachdb", false)); if (fDaemon) fServer = true; else fServer = GetBoolArg("-server", false); /* force fServer when running without GUI */ if (!fHaveGUI) fServer = true; fPrintToConsole = GetBoolArg("-printtoconsole"); fPrintToDebugLog = SoftSetBoolArg("-printtodebuglog", true); fLogTimestamps = GetBoolArg("-logtimestamps"); if (mapArgs.count("-timeout")) { int nNewTimeout = GetArg("-timeout", 5000); if (nNewTimeout > 0 && nNewTimeout < 600000) nConnectTimeout = nNewTimeout; }; if (mapArgs.count("-paytxfee")) { if (!ParseMoney(mapArgs["-paytxfee"], nTransactionFee)) return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s'"), mapArgs["-paytxfee"].c_str())); if (nTransactionFee > 0.25 * COIN) InitWarning(_("Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.")); }; fConfChange = GetBoolArg("-confchange", false); fEnforceCanonical = GetBoolArg("-enforcecanonical", true); if (mapArgs.count("-mininput")) { if (!ParseMoney(mapArgs["-mininput"], nMinimumInputValue)) return InitError(strprintf(_("Invalid amount for -mininput=<amount>: '%s'"), mapArgs["-mininput"].c_str())); }; // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log // Sanity check if (!InitSanityCheck()) return InitError(_("Initialization sanity check failed. PerfectCoin is shutting down.")); std::string strDataDir = GetDataDir().string(); std::string strWalletFileName = GetArg("-wallet", "wallet.dat"); // strWalletFileName must be a plain filename without a directory if (strWalletFileName != fs::basename(strWalletFileName) + fs::extension(strWalletFileName)) return InitError(strprintf(_("Wallet %s resides outside data directory %s."), strWalletFileName.c_str(), strDataDir.c_str())); // Make sure only a single Bitcoin process is using the data directory. fs::path pathLockFile = GetDataDir() / ".lock"; FILE* file = fopen(pathLockFile.string().c_str(), "a"); // empty lock file; created if it doesn't exist. if (file) fclose(file); 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. PerfectCoin is probably already running."), strDataDir.c_str())); 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("PerfectCoin version %s (%s)\n", FormatFullVersion().c_str(), CLIENT_DATE.c_str()); LogPrintf("Operating in %s mode.\n", GetNodeModeName(nNodeMode)); LogPrintf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION)); if (!fLogTimestamps) LogPrintf("Startup time: %s\n", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); LogPrintf("Default data directory %s\n", GetDefaultDataDir().string().c_str()); LogPrintf("Used data directory %s\n", strDataDir.c_str()); std::ostringstream strErrors; if (fDaemon) { fprintf(stdout, "PerfectCoin server starting\n"); fflush(stdout); }; int64_t nStart; /* ********************************************************* Step 4.5: adjust parameters for nNodeMode ********************************************************* */ switch (nNodeMode) { case NT_FULL: if (GetBoolArg("-nothinssupport")) { LogPrintf("Thin support disabled.\n"); nLocalServices &= ~(THIN_SUPPORT); }; if (GetBoolArg("-nothinstealth")) { LogPrintf("Thin stealth support disabled.\n"); nLocalServices &= ~(THIN_STEALTH); }; break; case NT_THIN: SetBoolArg("-staking", false); // -- clear services nLocalServices &= ~(NODE_NETWORK); nLocalServices &= ~(THIN_SUPPORT); nLocalServices &= ~(THIN_STAKE); nLocalServices &= ~(THIN_STEALTH); nLocalRequirements |= (THIN_SUPPORT); if (GetBoolArg("-thinfullindex")) { LogPrintf("Thin full index enabled.\n"); fThinFullIndex = true; } else { nThinIndexWindow = GetArg("-thinindexmax", 4096); if (nThinIndexWindow < 4096) { LogPrintf("Thin index window minimum size is %d.\n", 4096); nThinIndexWindow = 4096; }; LogPrintf("Thin index window size %d.\n", nThinIndexWindow); }; if (GetBoolArg("-nothinstealth")) { LogPrintf("Thin stealth disabled.\n"); } else { nLocalRequirements |= (THIN_STEALTH); }; break; default: break; }; // -- thin and full if (fNoSmsg) nLocalServices &= ~(SMSG_RELAY); if (initialiseRingSigs() != 0) return InitError("initialiseRingSigs() failed."); // ********************************************************* Step 5: verify database integrity uiInterface.InitMessage(_("Verifying database integrity...")); if (!bitdb.Open(GetDataDir())) { std::string msg = strprintf(_("Error initializing database environment %s!" " To recover, BACKUP THAT DIRECTORY, then remove" " everything from it except for wallet.dat."), strDataDir.c_str()); return InitError(msg); }; if (GetBoolArg("-salvagewallet")) { // Recover readable keypairs: if (!CWalletDB::Recover(bitdb, strWalletFileName, true)) return false; }; if (fs::exists(GetDataDir() / strWalletFileName)) { CDBEnv::VerifyResult r = bitdb.Verify(strWalletFileName, CWalletDB::Recover); if (r == CDBEnv::RECOVER_OK) { std::string msg = strprintf(_("Warning: wallet.dat corrupt, data salvaged!" " Original wallet.dat saved as wallet.{timestamp}.bak in %s; if" " your balance or transactions are incorrect you should" " restore from a backup."), strDataDir.c_str()); uiInterface.ThreadSafeMessageBox(msg, _("PerfectCoin"), CClientUIInterface::BTN_OK | CClientUIInterface::ICON_WARNING | CClientUIInterface::MODAL); }; if (r == CDBEnv::RECOVER_FAIL) return InitError(_("wallet.dat corrupt, salvage failed")); }; // ********************************************************* Step 6: network initialization nMaxThinPeers = GetArg("-maxthinpeers", 8); nBloomFilterElements = GetArg("-bloomfilterelements", 1536); if (mapArgs.count("-onlynet")) { std::set<enum Network> nets; BOOST_FOREACH(std::string snet, mapMultiArgs["-onlynet"]) { enum Network net = ParseNetwork(snet); if (net == NET_UNROUTABLE) return InitError(strprintf(_("Unknown network specified in -onlynet: '%s'"), snet.c_str())); nets.insert(net); }; for (int n = 0; n < NET_MAX; n++) { enum Network net = (enum Network)n; if (!nets.count(net)) SetLimited(net); }; };