init.cpp 49.6 KB
Newer Older
Tom Zander's avatar
Tom Zander committed
1 2 3 4
/*
 * This file is part of the Flowee project
 * Copyright (c) 2009-2010 Satoshi Nakamoto
 * Copyright (c) 2009-2015 The Bitcoin Core developers
5
 * Copyright (C) 2019-2020 Tom Zander <[email protected]>
Tom Zander's avatar
Tom Zander committed
6 7 8 9 10 11 12 13 14 15 16 17 18 19
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
20

21
#if defined(HAVE_CONFIG_H)
22
#include "config/flowee-config.h"
23 24
#endif

25
#include "init.h"
26
#include <SettingsDefaults.h>
27

28
#include "Application.h"
29
#include "addrman.h"
30
#include "amount.h"
Jorge Timón's avatar
Jorge Timón committed
31 32
#include "chain.h"
#include "chainparams.h"
33
#include "checkpoints.h"
Philip Kaufmann's avatar
Philip Kaufmann committed
34
#include "compat/sanity.h"
35
#include "consensus/validation.h"
36
#include "DoubleSpendProofStorage.h"
37 38
#include "httpserver.h"
#include "httprpc.h"
39
#include <primitives/key.h>
40
#include "main.h"
41
#include "miner.h"
42
#include "net.h"
43
#include "policy/policy.h"
44
#include "rpcserver.h"
45
#include "script/standard.h"
46
#include "script/sigcache.h"
47
#include "scheduler.h"
48
#include "BlocksDB.h"
Jorge Timón's avatar
Jorge Timón committed
49
#include "txmempool.h"
50
#include "torcontrol.h"
Tom Zander's avatar
Tom Zander committed
51
#include "UiInterface.h"
52 53 54 55
#include <util.h>
#include "serverutil.h"
#include <utilmoneystr.h>
#include <utilstrencodings.h>
56
#include "txorphancache.h"
57
#include "validationinterface.h"
58
#ifdef ENABLE_WALLET
Jorge Timón's avatar
Jorge Timón committed
59
#include "wallet/db.h"
60 61
#include "wallet/wallet.h"
#include "wallet/walletdb.h"
62
#endif
63
#include <validation/Engine.h>
64 65
#include <cstdint>
#include <cstdio>
66

Pieter Wuille's avatar
Pieter Wuille committed
67
#ifndef WIN32
68
#include <csignal>
69
#include "CrashCatcher.h"
70
#include <sys/resource.h>
71
#endif
72

73
#include <validation/VerifyDB.h>
74
#include <utxo/UnspentOutputDatabase.h>
75
#include <boost/algorithm/string/classification.hpp>
76
#include <boost/algorithm/string/predicate.hpp>
77
#include <boost/algorithm/string/replace.hpp>
78
#include <boost/algorithm/string/split.hpp>
Tom Zander's avatar
Tom Zander committed
79
#include <boost/algorithm/string/case_conv.hpp> // for to_lower()
Tom Zander's avatar
Tom Zander committed
80
#include <boost/lexical_cast.hpp>
81
#include <boost/filesystem.hpp>
82
#include <boost/function.hpp>
83
#include <boost/interprocess/sync/file_lock.hpp>
Wladimir J. van der Laan's avatar
Wladimir J. van der Laan committed
84
#include <boost/thread.hpp>
85
#include <openssl/crypto.h>
86
#include <boost/date_time/posix_time/posix_time.hpp>
87

88

89 90 91 92
#if ENABLE_ZMQ
#include "zmq/zmqnotificationinterface.h"
#endif

93
#ifdef ENABLE_WALLET
94
CWallet* pwalletMain = NULL;
95
#endif
96

97 98 99 100
#if ENABLE_ZMQ
static CZMQNotificationInterface* pzmqNotificationInterface = NULL;
#endif

101 102
#ifdef WIN32
// Win32 LevelDB doesn't use filedescriptors, and the ones used for
Corinne Dashjr's avatar
Corinne Dashjr committed
103
// accessing block files don't count towards the fd_set size limit
104 105 106 107 108 109
// anyway.
#define MIN_CORE_FILEDESCRIPTORS 0
#else
#define MIN_CORE_FILEDESCRIPTORS 150
#endif

110
/** Used to pass flags to the Bind() function */
111
enum BindFlags {
112 113
    BF_NONE         = 0,
    BF_EXPLICIT     = (1U << 0),
Pieter Wuille's avatar
Pieter Wuille committed
114 115
    BF_REPORT_ERROR = (1U << 1),
    BF_WHITELIST    = (1U << 2),
116 117
};

118
CClientUIInterface uiInterface; // Declared but not defined in ui_interface.h
119

120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
namespace {
/**
 * this function tries to raise the file descriptor limit to the requested number.
 * It returns the actual file descriptor limit (which may be more or less than nMinFD)
 */
int RaiseFileDescriptorLimit(int nMinFD) {
#if defined(WIN32)
    return 2048;
#else
    struct rlimit limitFD;
    if (getrlimit(RLIMIT_NOFILE, &limitFD) != -1) {
        if (limitFD.rlim_cur < (rlim_t)nMinFD) {
            limitFD.rlim_cur = nMinFD;
            if (limitFD.rlim_cur > limitFD.rlim_max)
                limitFD.rlim_cur = limitFD.rlim_max;
            setrlimit(RLIMIT_NOFILE, &limitFD);
            getrlimit(RLIMIT_NOFILE, &limitFD);
        }
        return limitFD.rlim_cur;
    }
    return nMinFD; // getrlimit failed, assume it's fine
#endif
}

#ifndef WIN32
boost::filesystem::path GetPidFile()
{
    boost::filesystem::path pathPidFile(GetArg("-pid", Settings::hubPidFilename()));
    if (!pathPidFile.is_complete()) pathPidFile = GetDataDir() / pathPidFile;
    return pathPidFile;
}

void CreatePidFile(const boost::filesystem::path &path, pid_t pid)
{
    FILE* file = fopen(path.string().c_str(), "w");
    if (file)
    {
        fprintf(file, "%d\n", pid);
        fclose(file);
    }
}
#endif

void ShrinkDebugFile()
{
    // Scroll hub.log if it's getting too big
    boost::filesystem::path pathLog = GetDataDir() / "hub.log";
    FILE* file = fopen(pathLog.string().c_str(), "r");
    if (file && boost::filesystem::file_size(pathLog) > 10 * 1000000)
    {
        // Restart the file with some of the end
        std::vector <char> vch(200000,0);
        fseek(file, -((long)vch.size()), SEEK_END);
        int nBytes = fread(begin_ptr(vch), 1, vch.size(), file);
        fclose(file);

        file = fopen(pathLog.string().c_str(), "w");
        if (file)
        {
            fwrite(begin_ptr(vch), 1, nBytes, file);
            fclose(file);
        }
    }
    else if (file != NULL)
        fclose(file);
}


}

190 191 192 193 194
//////////////////////////////////////////////////////////////////////////////
//
// Shutdown
//

Gavin Andresen's avatar
Gavin Andresen committed
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
//
// Thread management and startup/shutdown:
//
// The network-processing threads are all part of a thread group
// created by AppInit() or the Qt main() function.
//
// A clean exit happens when StartShutdown() or the SIGTERM
// signal handler sets fRequestShutdown, which triggers
// the DetectShutdownThread(), which interrupts the main thread group.
// DetectShutdownThread() then exits, which causes AppInit() to
// continue (it .joins the shutdown thread).
// Shutdown() is then
// called to clean up database connections, and stop other
// threads that should only be stopped after the main network-processing
// threads have exited.
//
// Note that if running -daemon the parent process returns from AppInit2
// before adding any threads to the threadGroup, so .join_all() returns
// immediately and the parent exits from main().
//
// Shutdown for Qt is very similar, only it uses a QTimer to detect
216 217
// fRequestShutdown getting set, and then does the normal Qt
// shutdown thing.
Gavin Andresen's avatar
Gavin Andresen committed
218 219 220
//

volatile bool fRequestShutdown = false;
221

222 223
void StartShutdown()
{
Gavin Andresen's avatar
Gavin Andresen committed
224
    fRequestShutdown = true;
225
}
226 227 228 229
bool ShutdownRequested()
{
    return fRequestShutdown;
}
230

231
static boost::scoped_ptr<ECCVerifyHandle> globalVerifyHandle;
232

233 234
UnspentOutputDatabase *g_utxo = nullptr;

235 236 237 238
void Interrupt(boost::thread_group& threadGroup)
{
    InterruptHTTPServer();
    InterruptRPC();
239
    InterruptTorControl();
240 241 242
    threadGroup.interrupt_all();
}

Gavin Andresen's avatar
Gavin Andresen committed
243
void Shutdown()
244
{
245
    logCritical(Log::Bitcoin) << "Shutdown in progress...";
246
    static CCriticalSection cs_Shutdown;
Gavin Andresen's avatar
Gavin Andresen committed
247
    TRY_LOCK(cs_Shutdown, lockShutdown);
248 249
    if (!lockShutdown)
        return;
250

251 252 253 254
    /// Note: Shutdown() must be able to handle cases in which AppInit2() failed part of the way,
    /// for example if the data directory was found to be locked.
    /// Be sure that anything that writes files or flushes caches only does this if the respective
    /// module was initialized.
255
    RenameThread("hub-shutoff");
256
    mempool.AddTransactionsUpdated(1);
257 258 259 260 261

    StopHTTPRPC();
    StopREST();
    StopRPC();
    StopHTTPServer();
262
#ifdef ENABLE_WALLET
263
    if (pwalletMain)
264
        pwalletMain->Flush(false);
265
#endif
266
    Mining::Stop();
267
    StopNode();
268
    StopTorControl();
Pieter Wuille's avatar
Pieter Wuille committed
269
    UnregisterNodeSignals(GetNodeSignals());
270

271 272 273
    Application::quit(0);
    Application::exec(); // waits for threads to finish.

274
    {
Gavin Andresen's avatar
Gavin Andresen committed
275
        LOCK(cs_main);
276 277 278
        FlushStateToDisk();
        delete g_utxo;
        g_utxo = nullptr;
Tom Zander's avatar
Tom Zander committed
279
        Blocks::DB::shutdown();
280
    }
281
#ifdef ENABLE_WALLET
282
    if (pwalletMain)
283
        pwalletMain->Flush(true);
284
#endif
285 286 287

#if ENABLE_ZMQ
    if (pzmqNotificationInterface) {
Tom Zander's avatar
Tom Zander committed
288
        ValidationNotifier().removeListener(pzmqNotificationInterface);
289 290 291 292 293
        delete pzmqNotificationInterface;
        pzmqNotificationInterface = NULL;
    }
#endif

294
#ifndef WIN32
295 296 297
    try {
        boost::filesystem::remove(GetPidFile());
    } catch (const boost::filesystem::filesystem_error& e) {
298
        logCritical(Log::Bitcoin) << "Shutdown: Unable to remove pidfile:" <<  e;
299
    }
300
#endif
Tom Zander's avatar
Tom Zander committed
301
    ValidationNotifier().removeAll();
302
#ifdef ENABLE_WALLET
303 304
    delete pwalletMain;
    pwalletMain = NULL;
305
#endif
306
    globalVerifyHandle.reset();
307
    ECC_Stop();
308
    logCritical(Log::Bitcoin) << "Shutdown: done";
309 310
}

311 312 313
/**
 * Signal handlers are very limited in what they are allowed to do, so:
 */
314 315 316 317 318
void HandleSIGTERM(int)
{
    fRequestShutdown = true;
}

Michael Hendricks's avatar
Michael Hendricks committed
319 320
void HandleSIGHUP(int)
{
321
    Log::Manager::instance()->reopenLogFiles();
Tom Zander's avatar
Tom Zander committed
322
    Log::Manager::instance()->parseConfig(GetConfigFile("logs.conf"), GetDataDir(true) / "hub.log");
Michael Hendricks's avatar
Michael Hendricks committed
323
}
324

325 326
bool static InitError(const std::string &str)
{
327
    uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_ERROR);
328 329 330 331 332
    return false;
}

bool static InitWarning(const std::string &str)
{
333
    uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_WARNING);
334 335 336
    return true;
}

337
bool static Bind(const CService &addr, unsigned int flags) {
338
    if (!(flags & BF_EXPLICIT) && IsLimited(addr))
339 340
        return false;
    std::string strError;
341
    if (!BindListenPort(addr, strError, (flags & BF_WHITELIST) != 0)) {
342
        if (flags & BF_REPORT_ERROR)
Pieter Wuille's avatar
Pieter Wuille committed
343 344 345
            return InitError(strError);
        return false;
    }
346 347 348
    return true;
}

349 350 351
void OnRPCStopped()
{
    cvBlockChange.notify_all();
Tom Zander's avatar
Tom Zander committed
352
    logInfo(Log::RPC) << "RPC stopped.";
353 354 355 356 357
}

void OnRPCPreCommand(const CRPCCommand& cmd)
{
    // Observe safe mode
358
    std::string strWarning = GetWarnings("rpc");
359
    if (strWarning != "" && !GetBoolArg("-disablesafemode", Settings::DefaultDisableSafemode) &&
360
        !cmd.okSafeMode)
361
        throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, std::string("Safe mode: ") + strWarning);
362 363
}

364
static void BlockNotifyCallback(bool initialSync, const CBlockIndex *pBlockIndex)
365
{
366 367 368
    if (initialSync || !pBlockIndex)
        return;

369 370
    std::string strCmd = GetArg("-blocknotify", "");

371
    boost::replace_all(strCmd, "%s", pBlockIndex->GetBlockHash().GetHex());
372 373 374
    boost::thread t(runCommand, strCmd); // thread runs free
}

mrbandrews's avatar
mrbandrews committed
375

376 377 378 379 380 381 382
/** Sanity checks
 *  Ensure that Bitcoin is running in a usable environment with all
 *  necessary library support.
 */
bool InitSanityCheck(void)
{
    if(!ECC_InitSanityCheck()) {
383
        InitError("Elliptic curve cryptography sanity check failure. Aborting.");
384 385
        return false;
    }
Cory Fields's avatar
Cory Fields committed
386 387
    if (!glibc_sanity_test() || !glibcxx_sanity_test())
        return false;
388 389 390 391

    return true;
}

392
bool AppInitServers()
393 394 395
{
    RPCServer::OnStopped(&OnRPCStopped);
    RPCServer::OnPreCommand(&OnRPCPreCommand);
396
    if (!InitHTTPServer())
397
        return false;
DesWurstes's avatar
DesWurstes committed
398
    StartRPC();
399 400
    if (!StartHTTPRPC())
        return false;
DesWurstes's avatar
DesWurstes committed
401 402 403
    if (GetBoolArg("-rest", Settings::DefaultRestEnable))
        StartREST();
    StartHTTPServer();
404 405 406
    return true;
}

407 408 409 410 411 412 413
// Parameter interaction based on rules
void InitParameterInteraction()
{
    // when specifying an explicit binding address, you want to listen on it
    // even when -connect or -proxy is specified
    if (mapArgs.count("-bind")) {
        if (SoftSetBoolArg("-listen", true))
Tom Zander's avatar
Tom Zander committed
414
            logCritical(Log::Net) << "parameter interaction: -bind set -> setting -listen=1";
415 416 417
    }
    if (mapArgs.count("-whitebind")) {
        if (SoftSetBoolArg("-listen", true))
Tom Zander's avatar
Tom Zander committed
418
            logCritical(Log::Net) << "parameter interaction: -whitebind set -> setting -listen=1";
419 420 421 422 423
    }

    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))
Tom Zander's avatar
Tom Zander committed
424
            logCritical(Log::Net) << "parameter interaction: -connect set -> setting -dnsseed=0";
425
        if (SoftSetBoolArg("-listen", false))
Tom Zander's avatar
Tom Zander committed
426
            logCritical(Log::Net) << "parameter interaction: -connect set -> setting -listen=0";
427 428 429 430 431
    }

    if (mapArgs.count("-proxy")) {
        // to protect privacy, do not listen by default if a default proxy server is specified
        if (SoftSetBoolArg("-listen", false))
Tom Zander's avatar
Tom Zander committed
432
            logCritical(Log::Proxy) << "parameter interaction: -proxy set -> setting -listen=0";
433 434 435
        // to protect privacy, do not use UPNP when a proxy is set. The user may still specify -listen=1
        // to listen locally, so don't rely on this happening through -listen below.
        if (SoftSetBoolArg("-upnp", false))
Tom Zander's avatar
Tom Zander committed
436
            logCritical(Log::Proxy) << "parameter interaction: -proxy set -> setting -upnp=0";
437 438
        // to protect privacy, do not discover addresses by default
        if (SoftSetBoolArg("-discover", false))
Tom Zander's avatar
Tom Zander committed
439
            logCritical(Log::Proxy) << "parameter interaction: -proxy set -> setting -discover=0";
440 441 442 443 444
    }

    if (!GetBoolArg("-listen", DEFAULT_LISTEN)) {
        // do not map ports or try to retrieve public IP when not listening (pointless)
        if (SoftSetBoolArg("-upnp", false))
Tom Zander's avatar
Tom Zander committed
445
            logCritical(Log::Net) << "parameter interaction: -listen=0 -> setting -upnp=0";
446
        if (SoftSetBoolArg("-discover", false))
Tom Zander's avatar
Tom Zander committed
447
            logCritical(Log::Net) << "parameter interaction: -listen=0 -> setting -discover=0";
448
        if (SoftSetBoolArg("-listenonion", false))
Tom Zander's avatar
Tom Zander committed
449
            logCritical(Log::Net) << "parameter interaction: -listen=0 -> setting -listenonion=0";
450 451 452 453 454
    }

    if (mapArgs.count("-externalip")) {
        // if an explicit public IP is specified, do not try to find others
        if (SoftSetBoolArg("-discover", false))
455
            logCritical(Log::Net) << "parameter interaction: -externalip set -> setting -discover=false";
456 457 458 459 460
    }

    if (GetBoolArg("-salvagewallet", false)) {
        // Rewrite just private keys: rescan to find transactions
        if (SoftSetBoolArg("-rescan", true))
461
            logCritical(Log::Wallet) << "parameter interaction: -salvagewallet -> setting -rescan=true";
462 463 464 465 466
    }

    // -zapwallettx implies a rescan
    if (GetBoolArg("-zapwallettxes", false)) {
        if (SoftSetBoolArg("-rescan", true))
467
            logCritical(Log::Wallet) << "parameter interaction: -zapwallettxes=<mode> -> setting -rescan=true";
468
    }
469

470
    // disable walletbroadcast and whitelistrelay in blocksonly mode
471
    if (GetBoolArg("-blocksonly", Settings::DefaultBlocksOnly)) {
472
        if (SoftSetBoolArg("-whitelistrelay", false))
473
            logCritical(Log::Net) << "parameter interaction: -blocksonly=true -> setting -whitelistrelay=false";
474 475
#ifdef ENABLE_WALLET
        if (SoftSetBoolArg("-walletbroadcast", false))
Tom Zander's avatar
Tom Zander committed
476
            logCritical(Log::Wallet) << "parameter interaction: -blocksonly=1 -> setting -walletbroadcast=0";
477 478
#endif
    }
479 480

    // Forcing relay from whitelisted hosts implies we will accept relays from them in the first place.
481
    if (GetBoolArg("-whitelistforcerelay", Settings::DefaultWhitelistForceRelay)) {
482
        if (SoftSetBoolArg("-whitelistrelay", true))
483
            logCritical(Log::Net) << "parameter interaction: -whitelistforcerelay=true -> setting -whitelistrelay=true";
484
    }
485 486 487 488 489 490 491 492

    const auto miningSize = GetArg("-blockmaxsize", -1);
    if (miningSize > 0x7FFFFFFF) { // overflow
        logCritical(Log::Mining) << "parameter -blockmaxsize is too large. Max is 31bit int";
        throw std::runtime_error("invalid parameter passed to -blockmaxsize");
    }
    const int32_t acceptSize = Policy::blockSizeAcceptLimit();
    if ((int) miningSize > acceptSize) {
Tom Zander's avatar
Tom Zander committed
493
        if (SoftSetArg("-blocksizeacceptlimit", boost::lexical_cast<std::string>((miningSize + 100000) / 1E6)))
494 495 496 497 498
            logCritical(Log::Net) << "parameter interaction: -blockmaxsize  N -> setting -blockacceptlimit=N";
        else
            throw std::runtime_error("Block Accept setting smaller than block mining size. Please adjust and restart");
    }
    assert(Policy::blockSizeAcceptLimit() >= miningSize);
499 500

    const int64_t mempoolMaxSize = GetArg("-maxmempool", Settings::DefaultMaxMempoolSize) * 4500000;
501 502
    if (mempoolMaxSize < miningSize * 4) {
        if (SoftSetArg("-maxmempool", boost::lexical_cast<std::string>(miningSize * 4)))
503 504 505
            logCritical(Log::Net) << "parameter interaction: -blockmaxsize  N -> setting -maxmempool=4N";
    }

506 507
}

508 509
void InitLogging()
{
510
    fLogIPs = GetBoolArg("-logips", DEFAULT_LOGIPS);
511

Tom Zander's avatar
Tom Zander committed
512
    Log::Manager::instance()->parseConfig(GetConfigFile("logs.conf"), GetDataDir(true) / "hub.log");
513
    logCritical(Log::Bitcoin) << "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
Tom Zander's avatar
Tom Zander committed
514 515
    logCritical(Log::Bitcoin) << "Flowee the Hub version " << CLIENT_BUILD.c_str()
                              << "Built:" << CLIENT_DATE.c_str();
516 517
}

518 519 520
/** Initialize bitcoin.
 *  @pre Parameters should be parsed and config file should be read.
 */
521
bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
522
{
Pieter Wuille's avatar
Pieter Wuille committed
523
    // ********************************************************* Step 1: setup
524
#ifdef _MSC_VER
525
    // Turn off Microsoft heap dump noise
526 527 528 529
    _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
    _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
#endif
#if _MSC_VER >= 1400
530
    // Disable confusing "helpful" text message on abort, Ctrl-C
531 532
    _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
#endif
533 534 535 536 537
#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
538 539
    // 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!
540 541 542 543 544
#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);
545
#endif
546

547 548 549 550
#ifdef USE_UNSAFE_RANDOM
    /* Intializes random number generator in case the operator wanted non-safe random */
    srand(unsigned(boost::posix_time::microsec_clock::local_time().time_of_day().total_microseconds()));
#endif
Tom Zander's avatar
Tom Zander committed
551

552
    if (!SetupNetworking())
553
        return InitError("Initializing networking failed");
554 555

#ifndef WIN32
556

557 558 559 560 561 562 563
    // 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);
Michael Hendricks's avatar
Michael Hendricks committed
564

Tom Zander's avatar
Tom Zander committed
565
    // Reopen hub.log on SIGHUP
Michael Hendricks's avatar
Michael Hendricks committed
566 567 568 569 570
    struct sigaction sa_hup;
    sa_hup.sa_handler = HandleSIGHUP;
    sigemptyset(&sa_hup.sa_mask);
    sa_hup.sa_flags = 0;
    sigaction(SIGHUP, &sa_hup, NULL);
fcicq's avatar
fcicq committed
571

572
    // Ignore SIGPIPE, otherwise it will bring the daemon down if the client closes unexpectedly
fcicq's avatar
fcicq committed
573
    signal(SIGPIPE, SIG_IGN);
574 575 576

    if (GetBoolArg("catch-crash", false))
        setupBacktraceCatcher();
577 578
#endif

Pieter Wuille's avatar
Pieter Wuille committed
579
    // ********************************************************* Step 2: parameter interactions
580
    const CChainParams& chainparams = Params();
581

582
    // also see: InitParameterInteraction()
583

584 585
    // Make sure enough file descriptors are available
    int nBind = std::max((int)mapArgs.count("-bind") + (int)mapArgs.count("-whitebind"), 1);
586
    int nUserMaxConnections = GetArg("-maxconnections", Settings::DefaultMaxPeerConnections);
587 588 589 590 591 592 593 594 595 596 597 598
    nMaxConnections = std::max(nUserMaxConnections, 0);

    // Trim requested connection counts, to fit into system limitations
    nMaxConnections = std::max(std::min(nMaxConnections, (int)(FD_SETSIZE - nBind - MIN_CORE_FILEDESCRIPTORS)), 0);
    int nFD = RaiseFileDescriptorLimit(nMaxConnections + MIN_CORE_FILEDESCRIPTORS);
    if (nFD < MIN_CORE_FILEDESCRIPTORS)
        return InitError(_("Not enough file descriptors available."));
    nMaxConnections = std::min(nFD - MIN_CORE_FILEDESCRIPTORS, nMaxConnections);

    if (nMaxConnections < nUserMaxConnections)
        InitWarning(strprintf(_("Reducing -maxconnections from %d to %d, because of system limitations."), nUserMaxConnections, nMaxConnections));

Pieter Wuille's avatar
Pieter Wuille committed
599 600
    // ********************************************************* Step 3: parameter-to-internal-flags

601
    fCheckpointsEnabled = GetBoolArg("-checkpoints", Settings::DefaultCheckpointsEnabled);
602

603
    // mempool limits
604 605
    int64_t nMempoolSizeMax = GetArg("-maxmempool", Settings::DefaultMaxMempoolSize) * 1000000;
    int64_t nMempoolSizeMin = GetArg("-limitdescendantsize", Settings::DefaultDescendantSizeLimit) * 1000 * 40;
606
    if (nMempoolSizeMax < 0 || nMempoolSizeMax < nMempoolSizeMin)
607
        return InitError(strprintf(_("-maxmempool must be at least %d MB"), std::ceil(nMempoolSizeMin / 1000000.0)));
608

609
    fServer = GetBoolArg("-server", false);
mrbandrews's avatar
mrbandrews committed
610

611
#ifdef ENABLE_WALLET
612
    bool fDisableWallet = GetBoolArg("-disablewallet", false);
613
#endif
614

615
    nConnectTimeout = GetArg("-timeout", Settings::DefaultConnectTimeout);
616
    if (nConnectTimeout <= 0)
617
        nConnectTimeout = Settings::DefaultConnectTimeout;
Pieter Wuille's avatar
Pieter Wuille committed
618

Gavin Andresen's avatar
Gavin Andresen committed
619 620 621 622 623 624 625 626
    // Fee-per-kilobyte amount considered the same as "free"
    // If you are mining, 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("-minrelaytxfee"))
    {
627
        CAmount n = 0;
628 629
        if (ParseMoney(mapArgs["-minrelaytxfee"], n) && n > 0) {
            logCritical(Log::Bitcoin) << "Setting min relay Transaction fee to" << n << "satoshi";
Gavin Andresen's avatar
Gavin Andresen committed
630
            ::minRelayTxFee = CFeeRate(n);
631
        } else {
632
            return InitError(strprintf(_("Invalid amount for -minrelaytxfee=<amount>: '%s'"), mapArgs["-minrelaytxfee"]));
633
        }
Gavin Andresen's avatar
Gavin Andresen committed
634
    }
Pieter Wuille's avatar
Pieter Wuille committed
635

636 637
    fRequireStandard = !GetBoolArg("-acceptnonstdtxn", !Params().RequireStandard());

638
#ifdef ENABLE_WALLET
Gavin Andresen's avatar
Gavin Andresen committed
639 640
    if (mapArgs.count("-mintxfee"))
    {
641
        CAmount n = 0;
Gavin Andresen's avatar
Gavin Andresen committed
642 643 644 645 646
        if (ParseMoney(mapArgs["-mintxfee"], n) && n > 0)
            CWallet::minTxFee = CFeeRate(n);
        else
            return InitError(strprintf(_("Invalid amount for -mintxfee=<amount>: '%s'"), mapArgs["-mintxfee"]));
    }
647 648 649 650 651 652 653 654 655
    if (mapArgs.count("-fallbackfee"))
    {
        CAmount nFeePerK = 0;
        if (!ParseMoney(mapArgs["-fallbackfee"], nFeePerK))
            return InitError(strprintf(_("Invalid amount for -fallbackfee=<amount>: '%s'"), mapArgs["-fallbackfee"]));
        if (nFeePerK > nHighTransactionFeeWarning)
            InitWarning(_("-fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available."));
        CWallet::fallbackFee = CFeeRate(nFeePerK);
    }
Pieter Wuille's avatar
Pieter Wuille committed
656 657
    if (mapArgs.count("-paytxfee"))
    {
658
        CAmount nFeePerK = 0;
Gavin Andresen's avatar
Gavin Andresen committed
659
        if (!ParseMoney(mapArgs["-paytxfee"], nFeePerK))
660
            return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s'"), mapArgs["-paytxfee"]));
Gavin Andresen's avatar
Gavin Andresen committed
661
        if (nFeePerK > nHighTransactionFeeWarning)
662
            InitWarning(_("-paytxfee is set very high! This is the transaction fee you will pay if you send a transaction."));
Gavin Andresen's avatar
Gavin Andresen committed
663
        payTxFee = CFeeRate(nFeePerK, 1000);
Gavin Andresen's avatar
Gavin Andresen committed
664
        if (payTxFee < ::minRelayTxFee)
665 666
        {
            return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"),
Gavin Andresen's avatar
Gavin Andresen committed
667
                                       mapArgs["-paytxfee"], ::minRelayTxFee.ToString()));
668
        }
Pieter Wuille's avatar
Pieter Wuille committed
669
    }
670 671 672 673
    if (mapArgs.count("-maxtxfee"))
    {
        CAmount nMaxFee = 0;
        if (!ParseMoney(mapArgs["-maxtxfee"], nMaxFee))
674
            return InitError(strprintf(_("Invalid amount for -maxtxfee=<amount>: '%s'"), mapArgs["-maxtxfee"]));
675
        if (nMaxFee > nHighTransactionMaxFeeWarning)
676
            InitWarning(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction."));
677 678 679 680 681 682 683
        maxTxFee = nMaxFee;
        if (CFeeRate(maxTxFee, 1000) < ::minRelayTxFee)
        {
            return InitError(strprintf(_("Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"),
                                       mapArgs["-maxtxfee"], ::minRelayTxFee.ToString()));
        }
    }
684 685 686
    nTxConfirmTarget = GetArg("-txconfirmtarget", Settings::defaultTxConfirmTarget);
    bSpendZeroConfChange = GetBoolArg("-spendzeroconfchange", Settings::DefaultSpendZeroconfChange);
    fSendFreeTransactions = GetBoolArg("-sendfreetransactions", Settings::DefaultSendFreeTransactions);
Pieter Wuille's avatar
Pieter Wuille committed
687

688
    std::string strWalletFile = GetArg("-wallet", "wallet.dat");
689 690
#endif // ENABLE_WALLET

691 692
    fIsBareMultisigStd = GetBoolArg("-permitbaremultisig", Settings::DefaultPermitBareMultisig);
    fAcceptDatacarrier = GetBoolArg("-datacarrier", Settings::DefaultAcceptDataCarrier);
693
    nMaxDatacarrierBytes = GetArg("-datacarriersize", nMaxDatacarrierBytes);
694

695 696 697
    // Option to startup with mocktime set (used for regression testing):
    SetMockTime(GetArg("-mocktime", 0)); // SetMockTime(0) is a no-op

698 699 700
    if (GetBoolArg("-peerbloomfilters", true))
        nLocalServices |= NODE_BLOOM;

701
    if (GetBoolArg("-use-thinblocks", false))
702
        nLocalServices |= NODE_XTHIN;
703 704 705 706 707
    if (Params().NetworkIDString() == CBaseChainParams::MAIN) {
        if (Policy::blockSizeAcceptLimit() < 8000000)
            return InitError("The block size accept limit is too low, the minimum is 8MB. The Hub is shutting down.");
        if (GetArg("-blockmaxsize", Settings::DefaultBlockMAxSize) <= 1000000)
            return InitError("The maxblocksize mining limit is too low, it should be over 1MB. The Hub is shutting down.");
708
    }
709
    else if (Params().NetworkIDString() == CBaseChainParams::REGTEST) { // setup for testing to not use so much disk space.
710 711 712
        UnspentOutputDatabase::setSmallLimits();
    }

Tom Zander's avatar
Tom Zander committed
713
    // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, hub log
714

715 716
    // Initialize elliptic curve code
    ECC_Start();
717
    globalVerifyHandle.reset(new ECCVerifyHandle());
718

DesWurstes's avatar
DesWurstes committed
719 720 721
    // Initialize SigCache
    InitSignatureCache();

722 723
    // Sanity check
    if (!InitSanityCheck())
Tom Zander's avatar
Tom Zander committed
724
        return InitError(_("Initialization sanity check failed. The Hub is shutting down."));
Pieter Wuille's avatar
Pieter Wuille committed
725

726
    std::string strDataDir = GetDataDir().string();
727
#ifdef ENABLE_WALLET
728 729
    // Wallet file must be a plain filename without a directory
    if (strWalletFile != boost::filesystem::basename(strWalletFile) + boost::filesystem::extension(strWalletFile))
730
        return InitError(strprintf(_("Wallet %s resides outside data directory %s"), strWalletFile, strDataDir));
731
#endif
Pieter Wuille's avatar
Pieter Wuille committed
732 733 734 735
    // 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);
736 737 738 739

    try {
        static boost::interprocess::file_lock lock(pathLockFile.string().c_str());
        if (!lock.try_lock())
Tom Zander's avatar
Tom Zander committed
740
            return InitError(strprintf(_("Cannot obtain a lock on data directory %s. The Hub is probably already running."), strDataDir));
741
    } catch(const boost::interprocess::interprocess_exception& e) {
Tom Zander's avatar
Tom Zander committed
742
        return InitError(strprintf(_("Cannot obtain a lock on data directory %s. The Hub is probably already running.") + " %s.", strDataDir, e.what()));
743 744
    }

745 746 747
#ifndef WIN32
    CreatePidFile(GetPidFile(), getpid());
#endif
748
    if (GetBoolArg("-shrinkdebugfile", true))
749
        ShrinkDebugFile();
750

751
#ifdef ENABLE_WALLET
Tom Zander's avatar
Tom Zander committed
752
    logCritical(Log::Wallet) << "Using BerkeleyDB version" << DbEnv::version(0, 0, 0);
753
#endif
Tom Zander's avatar
Tom Zander committed
754 755 756
    logCritical(Log::Bitcoin) << "Startup time:" << DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime());
    logCritical(Log::Bitcoin) << "Using data directory" << strDataDir;
    logCritical(Log::Bitcoin) << "Using config file" << GetConfigFile().string();
757
    logCritical(Log::Bitcoin) << "Using log-config file" << GetConfigFile("logs.conf").string();
Tom Zander's avatar
Tom Zander committed
758 759
    logInfo(Log::Net) << "Using at most" << nMaxConnections  << "connections.";
    logInfo(Log::Internals) << nFD << "file descriptors available";
Pieter Wuille's avatar
Pieter Wuille committed
760
    std::ostringstream strErrors;
761

762
    // Start the lightweight task scheduler thread
763 764
    CScheduler::Function serviceLoop = std::bind(&CScheduler::serviceQueue, &scheduler);
    threadGroup.create_thread(std::bind(&TraceThread<CScheduler::Function>, "scheduler", serviceLoop));
765

766 767 768 769 770 771 772 773
    /* 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
     * be disabled when initialisation is finished.
     */
    if (fServer)
    {
        uiInterface.InitMessage.connect(SetRPCWarmupStatus);
774
        if (!AppInitServers())
Tom Zander's avatar
Tom Zander committed
775
            return InitError(_("Unable to start HTTP server. See hub log for details."));
776 777
    }

778
    Application::instance()->validation()->setMempool(&mempool);
779
    scheduler.scheduleEvery(std::bind(&DoubleSpendProofStorage::periodicCleanup,  mempool.doubleSpendProofStorage()), 60);
780

781
    // ********************************************************* Step 5: verify wallet database integrity
782
#ifdef ENABLE_WALLET
783
    if (!fDisableWallet) {
Tom Zander's avatar
Tom Zander committed
784
        logCritical(Log::Wallet) << "Using wallet" << strWalletFile;
785
        uiInterface.InitMessage(_("Verifying wallet..."));
786

787 788
        std::string warningString;
        std::string errorString;
789

790 791
        if (!CWallet::Verify(strWalletFile, warningString, errorString))
            return false;
Philip Kaufmann's avatar