init.cpp 20.9 KB
Newer Older
1
// Copyright (c) 2009-2010 Satoshi Nakamoto
Gavin Andresen's avatar
Gavin Andresen committed
2
// Copyright (c) 2009-2012 The Bitcoin developers
3
4
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
5
#include "db.h"
6
#include "walletdb.h"
Wladimir J. van der Laan's avatar
Wladimir J. van der Laan committed
7
#include "bitcoinrpc.h"
8
9
#include "net.h"
#include "init.h"
Pieter Wuille's avatar
Pieter Wuille committed
10
11
#include "util.h"
#include "ui_interface.h"
12
#include <boost/filesystem.hpp>
13
#include <boost/filesystem/fstream.hpp>
14
#include <boost/filesystem/convenience.hpp>
15
#include <boost/interprocess/sync/file_lock.hpp>
16

Pieter Wuille's avatar
Pieter Wuille committed
17
18
#ifndef WIN32
#include <signal.h>
19
#endif
20

21
22
23
using namespace std;
using namespace boost;

24
25
CWallet* pwalletMain;

26
27
28
29
30
31
32
//////////////////////////////////////////////////////////////////////////////
//
// Shutdown
//

void ExitTimeout(void* parg)
{
Gavin Andresen's avatar
Gavin Andresen committed
33
#ifdef WIN32
34
35
36
37
38
39
40
41
42
    Sleep(5000);
    ExitProcess(0);
#endif
}

void Shutdown(void* parg)
{
    static CCriticalSection cs_Shutdown;
    static bool fTaken;
43
    bool fFirstThread = false;
44
    {
45
46
47
48
49
50
        TRY_LOCK(cs_Shutdown, lockShutdown);
        if (lockShutdown)
        {
            fFirstThread = !fTaken;
            fTaken = true;
        }
51
52
53
54
55
56
    }
    static bool fExit;
    if (fFirstThread)
    {
        fShutdown = true;
        nTransactionsUpdated++;
57
        DBFlush(false);
58
        StopNode();
59
        DBFlush(true);
60
        boost::filesystem::remove(GetPidFile());
61
62
        UnregisterWallet(pwalletMain);
        delete pwalletMain;
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
        CreateThread(ExitTimeout, NULL);
        Sleep(50);
        printf("Bitcoin exiting\n\n");
        fExit = true;
        exit(0);
    }
    else
    {
        while (!fExit)
            Sleep(500);
        Sleep(100);
        ExitThread(0);
    }
}

void HandleSIGTERM(int)
{
    fRequestShutdown = true;
}






//////////////////////////////////////////////////////////////////////////////
//
// Start
//
Gavin Andresen's avatar
Gavin Andresen committed
92
#if !defined(QT_GUI)
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
int main(int argc, char* argv[])
{
    bool fRet = false;
    fRet = AppInit(argc, argv);

    if (fRet && fDaemon)
        return 0;

    return 1;
}
#endif

bool AppInit(int argc, char* argv[])
{
    bool fRet = false;
    try
    {
        fRet = AppInit2(argc, argv);
    }
    catch (std::exception& e) {
        PrintException(&e, "AppInit()");
    } catch (...) {
        PrintException(NULL, "AppInit()");
    }
    if (!fRet)
        Shutdown(NULL);
    return fRet;
}

bool AppInit2(int argc, char* argv[])
{
#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
Gavin Andresen's avatar
Gavin Andresen committed
133
#ifndef WIN32
134
135
    umask(077);
#endif
Gavin Andresen's avatar
Gavin Andresen committed
136
#ifndef WIN32
137
138
139
140
141
142
143
144
145
146
147
148
149
    // 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);
    sigaction(SIGHUP, &sa, NULL);
#endif

    //
    // Parameters
    //
Gavin Andresen's avatar
Gavin Andresen committed
150
    // If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's main()
151
#if !defined(QT_GUI)
152
    ParseParameters(argc, argv);
153
    if (!boost::filesystem::is_directory(GetDataDir(false)))
154
    {
Gavin Andresen's avatar
Gavin Andresen committed
155
156
        fprintf(stderr, "Error: Specified directory does not exist\n");
        Shutdown(NULL);
157
    }
158
    ReadConfigFile(mapArgs, mapMultiArgs);
Gavin Andresen's avatar
Gavin Andresen committed
159
#endif
160
161
162
163
164
165

    if (mapArgs.count("-?") || mapArgs.count("--help"))
    {
        string strUsage = string() +
          _("Bitcoin version") + " " + FormatFullVersion() + "\n\n" +
          _("Usage:") + "\t\t\t\t\t\t\t\t\t\t\n" +
166
            "  bitcoind [options]                   \t  " + "\n" +
167
168
169
170
171
172
173
174
175
            "  bitcoind [options] <command> [params]\t  " + _("Send command to -server or bitcoind") + "\n" +
            "  bitcoind [options] help              \t\t  " + _("List commands") + "\n" +
            "  bitcoind [options] help <command>    \t\t  " + _("Get help for a command") + "\n" +
          _("Options:") + "\n" +
            "  -conf=<file>     \t\t  " + _("Specify configuration file (default: bitcoin.conf)") + "\n" +
            "  -pid=<file>      \t\t  " + _("Specify pid file (default: bitcoind.pid)") + "\n" +
            "  -gen             \t\t  " + _("Generate coins") + "\n" +
            "  -gen=0           \t\t  " + _("Don't generate coins") + "\n" +
            "  -min             \t\t  " + _("Start minimized") + "\n" +
176
            "  -splash          \t\t  " + _("Show splash screen on startup (default: 1)") + "\n" +
177
            "  -datadir=<dir>   \t\t  " + _("Specify data directory") + "\n" +
Pieter Wuille's avatar
Pieter Wuille committed
178
            "  -dbcache=<n>     \t\t  " + _("Set database cache size in megabytes (default: 25)") + "\n" +
179
            "  -dblogsize=<n>   \t\t  " + _("Set database disk log size in megabytes (default: 100)") + "\n" +
180
181
182
183
184
            "  -timeout=<n>     \t  "   + _("Specify connection timeout (in milliseconds)") + "\n" +
            "  -proxy=<ip:port> \t  "   + _("Connect through socks4 proxy") + "\n" +
            "  -dns             \t  "   + _("Allow DNS lookups for addnode and connect") + "\n" +
            "  -port=<port>     \t\t  " + _("Listen for connections on <port> (default: 8333 or testnet: 18333)") + "\n" +
            "  -maxconnections=<n>\t  " + _("Maintain at most <n> connections to peers (default: 125)") + "\n" +
185
            "  -addnode=<ip>    \t  "   + _("Add a node to connect to and attempt to keep the connection open") + "\n" +
186
            "  -connect=<ip>    \t\t  " + _("Connect only to the specified node") + "\n" +
187
188
            "  -irc             \t  "   + _("Find peers using internet relay chat (default: 0)") + "\n" +
            "  -listen          \t  "   + _("Accept connections from outside (default: 1)") + "\n" +
189
190
191
#ifdef QT_GUI
            "  -lang=<lang>     \t\t  " + _("Set language, for example \"de_DE\" (default: system locale)") + "\n" +
#endif
192
            "  -dnsseed         \t  "   + _("Find peers using DNS lookup (default: 1)") + "\n" +
193
194
195
196
            "  -banscore=<n>    \t  "   + _("Threshold for disconnecting misbehaving peers (default: 100)") + "\n" +
            "  -bantime=<n>     \t  "   + _("Number of seconds to keep misbehaving peers from reconnecting (default: 86400)") + "\n" +
            "  -maxreceivebuffer=<n>\t  " + _("Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000)") + "\n" +
            "  -maxsendbuffer=<n>\t  "   + _("Maximum per-connection send buffer, <n>*1000 bytes (default: 10000)") + "\n" +
197
198
#ifdef USE_UPNP
#if USE_UPNP
199
            "  -upnp            \t  "   + _("Use Universal Plug and Play to map the listening port (default: 1)") + "\n" +
200
#else
201
            "  -upnp            \t  "   + _("Use Universal Plug and Play to map the listening port (default: 0)") + "\n" +
202
203
#endif
#endif
204
            "  -paytxfee=<amt>  \t  "   + _("Fee per KB to add to transactions you send") + "\n" +
205
#ifdef QT_GUI
206
            "  -server          \t\t  " + _("Accept command line and JSON-RPC commands") + "\n" +
207
#endif
208
#if !defined(WIN32) && !defined(QT_GUI)
209
            "  -daemon          \t\t  " + _("Run in the background as a daemon and accept commands") + "\n" +
210
#endif
211
212
213
214
            "  -testnet         \t\t  " + _("Use the test network") + "\n" +
            "  -debug           \t\t  " + _("Output extra debugging information") + "\n" +
            "  -logtimestamps   \t  "   + _("Prepend debug output with timestamp") + "\n" +
            "  -printtoconsole  \t  "   + _("Send trace/debug info to console instead of debug.log file") + "\n" +
215
#ifdef WIN32
216
            "  -printtodebugger \t  "   + _("Send trace/debug info to debugger") + "\n" +
217
#endif
218
219
220
221
222
            "  -rpcuser=<user>  \t  "   + _("Username for JSON-RPC connections") + "\n" +
            "  -rpcpassword=<pw>\t  "   + _("Password for JSON-RPC connections") + "\n" +
            "  -rpcport=<port>  \t\t  " + _("Listen for JSON-RPC connections on <port> (default: 8332)") + "\n" +
            "  -rpcallowip=<ip> \t\t  " + _("Allow JSON-RPC connections from specified IP address") + "\n" +
            "  -rpcconnect=<ip> \t  "   + _("Send commands to node running on <ip> (default: 127.0.0.1)") + "\n" +
223
            "  -blocknotify=<cmd> "     + _("Execute command when the best block changes (%s in cmd is replaced by block hash)") + "\n" +
224
            "  -upgradewallet   \t  "   + _("Upgrade wallet to latest format") + "\n" +
225
            "  -keypool=<n>     \t  "   + _("Set key pool size to <n> (default: 100)") + "\n" +
226
227
228
            "  -rescan          \t  "   + _("Rescan the block chain for missing wallet transactions") + "\n" +
            "  -checkblocks=<n> \t\t  " + _("How many blocks to check at startup (default: 2500, 0 = all)") + "\n" +
            "  -checklevel=<n>  \t\t  " + _("How thorough the block verification is (0-6, default: 1)") + "\n";
229
230

        strUsage += string() +
231
232
233
234
235
            _("\nSSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n" +
            "  -rpcssl                                \t  " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n" +
            "  -rpcsslcertificatechainfile=<file.cert>\t  " + _("Server certificate file (default: server.cert)") + "\n" +
            "  -rpcsslprivatekeyfile=<file.pem>       \t  " + _("Server private key (default: server.pem)") + "\n" +
            "  -rpcsslciphers=<ciphers>               \t  " + _("Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)") + "\n";
236
237

        strUsage += string() +
238
            "  -?               \t\t  " + _("This help message") + "\n";
239
240
241

        // Remove tabs
        strUsage.erase(std::remove(strUsage.begin(), strUsage.end(), '\t'), strUsage.end());
242
243
#if defined(QT_GUI) && defined(WIN32)
        // On windows, show a message box, as there is no stderr
244
        ThreadSafeMessageBox(strUsage, _("Usage"), wxOK | wxMODAL);
245
#else
246
        fprintf(stderr, "%s", strUsage.c_str());
247
#endif
248
249
250
        return false;
    }

251
    fTestNet = GetBoolArg("-testnet");
252
253
254
255
256
    if (fTestNet)
    {
        SoftSetBoolArg("-irc", true);
    }

257
258
    fDebug = GetBoolArg("-debug");

259
#if !defined(WIN32) && !defined(QT_GUI)
260
261
262
263
264
265
266
267
268
269
270
    fDaemon = GetBoolArg("-daemon");
#else
    fDaemon = false;
#endif

    if (fDaemon)
        fServer = true;
    else
        fServer = GetBoolArg("-server");

    /* force fServer when running without GUI */
Gavin Andresen's avatar
Gavin Andresen committed
271
#if !defined(QT_GUI)
272
    fServer = true;
273
#endif
274
275
276
277
    fPrintToConsole = GetBoolArg("-printtoconsole");
    fPrintToDebugger = GetBoolArg("-printtodebugger");
    fLogTimestamps = GetBoolArg("-logtimestamps");

278
#ifndef QT_GUI
279
    for (int i = 1; i < argc; i++)
280
        if (!IsSwitchChar(argv[i][0]) && !(strlen(argv[i]) > 7 && strncasecmp(argv[i], "bitcoin:", 8) == 0))
281
282
283
284
285
286
287
            fCommandLine = true;

    if (fCommandLine)
    {
        int ret = CommandLineRPC(argc, argv);
        exit(ret);
    }
288
#endif
289

290
#if !defined(WIN32) && !defined(QT_GUI)
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
    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

312
    if (!fDebug)
313
314
        ShrinkDebugFile();
    printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
Pieter Wuille's avatar
Pieter Wuille committed
315
    printf("Bitcoin version %s (%s)\n", FormatFullVersion().c_str(), CLIENT_DATE.c_str());
316
    printf("Default data directory %s\n", GetDefaultDataDir().string().c_str());
317
318
319
320
321
322
323
324
325
326

    if (GetBoolArg("-loadblockindextest"))
    {
        CTxDB txdb("r");
        txdb.LoadBlockIndex();
        PrintBlockTree();
        return false;
    }

    // Make sure only a single bitcoin process is using the data directory.
327
328
    boost::filesystem::path pathLockFile = GetDataDir() / ".lock";
    FILE* file = fopen(pathLockFile.string().c_str(), "a"); // empty lock file; created if it doesn't exist.
329
    if (file) fclose(file);
330
    static boost::interprocess::file_lock lock(pathLockFile.string().c_str());
331
332
    if (!lock.try_lock())
    {
333
        ThreadSafeMessageBox(strprintf(_("Cannot obtain a lock on data directory %s.  Bitcoin is probably already running."), GetDataDir().string().c_str()), _("Bitcoin"), wxOK|wxMODAL);
334
335
336
        return false;
    }

337
    std::ostringstream strErrors;
338
339
340
341
342
    //
    // Load data files
    //
    if (fDaemon)
        fprintf(stdout, "bitcoin server starting\n");
343
    int64 nStart;
344

345
    InitMessage(_("Loading addresses..."));
346
347
348
    printf("Loading addresses...\n");
    nStart = GetTimeMillis();
    if (!LoadAddresses())
349
        strErrors << _("Error loading addr.dat") << "\n";
350
351
    printf(" addresses   %15"PRI64d"ms\n", GetTimeMillis() - nStart);

352
    InitMessage(_("Loading block index..."));
353
354
355
    printf("Loading block index...\n");
    nStart = GetTimeMillis();
    if (!LoadBlockIndex())
356
        strErrors << _("Error loading blkindex.dat") << "\n";
357
358
359
360
361
362
363
364
365

    // 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)
    {
        printf("Shutdown requested. Exiting.\n");
        return false;
    }
366
367
    printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart);

368
    InitMessage(_("Loading wallet..."));
369
370
371
    printf("Loading wallet...\n");
    nStart = GetTimeMillis();
    bool fFirstRun;
372
    pwalletMain = new CWallet("wallet.dat");
Matt Corallo's avatar
Matt Corallo committed
373
374
375
376
    int nLoadWalletRet = pwalletMain->LoadWallet(fFirstRun);
    if (nLoadWalletRet != DB_LOAD_OK)
    {
        if (nLoadWalletRet == DB_CORRUPT)
377
            strErrors << _("Error loading wallet.dat: Wallet corrupted") << "\n";
Matt Corallo's avatar
Matt Corallo committed
378
        else if (nLoadWalletRet == DB_TOO_NEW)
379
            strErrors << _("Error loading wallet.dat: Wallet requires newer version of Bitcoin") << "\n";
380
381
        else if (nLoadWalletRet == DB_NEED_REWRITE)
        {
382
            strErrors << _("Wallet needed to be rewritten: restart Bitcoin to complete") << "\n";
383
            printf("%s", strErrors.str().c_str());
384
            ThreadSafeMessageBox(strErrors.str(), _("Bitcoin"), wxOK | wxICON_ERROR | wxMODAL);
385
386
            return false;
        }
Matt Corallo's avatar
Matt Corallo committed
387
        else
388
            strErrors << _("Error loading wallet.dat") << "\n";
Matt Corallo's avatar
Matt Corallo committed
389
    }
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419

    if (GetBoolArg("-upgradewallet", fFirstRun))
    {
        int nMaxVersion = GetArg("-upgradewallet", 0);
        if (nMaxVersion == 0) // the -walletupgrade without argument case
        {
            printf("Performing wallet upgrade to %i\n", FEATURE_LATEST);
            nMaxVersion = CLIENT_VERSION;
            pwalletMain->SetMinVersion(FEATURE_LATEST); // permanently upgrade the wallet immediately
        }
        else
            printf("Allowing wallet upgrade up to %i\n", nMaxVersion);
        if (nMaxVersion < pwalletMain->GetVersion())
            strErrors << _("Cannot downgrade wallet") << "\n";
        pwalletMain->SetMaxVersion(nMaxVersion);
    }

    if (fFirstRun)
    {
        // Create new keyUser and set as default key
        RandAddSeedPerfmon();

        std::vector<unsigned char> newDefaultKey;
        if (!pwalletMain->GetKeyFromPool(newDefaultKey, false))
            strErrors << _("Cannot initialize keypool") << "\n";
        pwalletMain->SetDefaultKey(newDefaultKey);
        if (!pwalletMain->SetAddressBookName(CBitcoinAddress(pwalletMain->vchDefaultKey), ""))
            strErrors << _("Cannot write default address") << "\n";
    }

420
    printf("%s", strErrors.str().c_str());
421
422
    printf(" wallet      %15"PRI64d"ms\n", GetTimeMillis() - nStart);

423
424
    RegisterWallet(pwalletMain);

425
426
427
428
429
    CBlockIndex *pindexRescan = pindexBest;
    if (GetBoolArg("-rescan"))
        pindexRescan = pindexGenesisBlock;
    else
    {
430
        CWalletDB walletdb("wallet.dat");
431
432
433
434
435
436
        CBlockLocator locator;
        if (walletdb.ReadBestBlock(locator))
            pindexRescan = locator.GetBlockIndex();
    }
    if (pindexBest != pindexRescan)
    {
437
        InitMessage(_("Rescanning..."));
438
439
        printf("Rescanning last %i blocks (from block %i)...\n", pindexBest->nHeight - pindexRescan->nHeight, pindexRescan->nHeight);
        nStart = GetTimeMillis();
440
        pwalletMain->ScanForWalletTransactions(pindexRescan, true);
441
442
443
        printf(" rescan      %15"PRI64d"ms\n", GetTimeMillis() - nStart);
    }

444
    InitMessage(_("Done loading"));
445
446
    printf("Done loading\n");

447
448
449
450
451
452
    //// debug print
    printf("mapBlockIndex.size() = %d\n",   mapBlockIndex.size());
    printf("nBestHeight = %d\n",            nBestHeight);
    printf("setKeyPool.size() = %d\n",      pwalletMain->setKeyPool.size());
    printf("mapWallet.size() = %d\n",       pwalletMain->mapWallet.size());
    printf("mapAddressBook.size() = %d\n",  pwalletMain->mapAddressBook.size());
453

454
    if (!strErrors.str().empty())
455
    {
456
        ThreadSafeMessageBox(strErrors.str(), _("Bitcoin"), wxOK | wxICON_ERROR | wxMODAL);
457
458
459
460
        return false;
    }

    // Add wallet transactions that aren't already in a block to mapTransactions
461
    pwalletMain->ReacceptWalletTransactions();
462

463
464
465
466
    // Note: Bitcoin-QT stores several settings in the wallet, so we want
    // to load the wallet BEFORE parsing command-line arguments, so
    // the command-line/bitcoin.conf settings override GUI setting.

467
468
469
470
471
472
473
474
475
    //
    // Parameters
    //
    if (GetBoolArg("-printblockindex") || GetBoolArg("-printblocktree"))
    {
        PrintBlockTree();
        return false;
    }

476
477
478
479
480
481
482
    if (mapArgs.count("-timeout"))
    {
        int nNewTimeout = GetArg("-timeout", 5000);
        if (nNewTimeout > 0 && nNewTimeout < 600000)
            nConnectTimeout = nNewTimeout;
    }

483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
    if (mapArgs.count("-printblock"))
    {
        string strMatch = mapArgs["-printblock"];
        int nFound = 0;
        for (map<uint256, CBlockIndex*>::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();
                printf("\n");
                nFound++;
            }
        }
        if (nFound == 0)
            printf("No blocks matching %s were found\n", strMatch.c_str());
        return false;
    }

    if (mapArgs.count("-proxy"))
    {
        fUseProxy = true;
Pieter Wuille's avatar
Pieter Wuille committed
509
        addrProxy = CService(mapArgs["-proxy"], 9050);
510
511
        if (!addrProxy.IsValid())
        {
512
            ThreadSafeMessageBox(_("Invalid -proxy address"), _("Bitcoin"), wxOK | wxMODAL);
513
514
515
516
            return false;
        }
    }

Pieter Wuille's avatar
Pieter Wuille committed
517
    bool fTor = (fUseProxy && addrProxy.GetPort() == 9050);
518
519
    if (fTor)
    {
520
        // Use SoftSetBoolArg here so user can override any of these if they wish.
521
        // Note: the GetBoolArg() calls for all of these must happen later.
522
523
524
        SoftSetBoolArg("-listen", false);
        SoftSetBoolArg("-irc", false);
        SoftSetBoolArg("-dnsseed", false);
525
526
        SoftSetBoolArg("-upnp", false);
        SoftSetBoolArg("-dns", false);
527
528
529
    }

    fAllowDNS = GetBoolArg("-dns");
530
    fNoListen = !GetBoolArg("-listen", true);
531

532
533
534
535
536
    // 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));
537

538
539
540
541
542
    if (!fNoListen)
    {
        std::string strError;
        if (!BindListenPort(strError))
        {
543
            ThreadSafeMessageBox(strError, _("Bitcoin"), wxOK | wxMODAL);
544
545
546
547
            return false;
        }
    }

548
549
550
551
    if (mapArgs.count("-addnode"))
    {
        BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
        {
Pieter Wuille's avatar
Pieter Wuille committed
552
            CAddress addr(CService(strAddr, GetDefaultPort(), fAllowDNS));
553
554
            addr.nTime = 0; // so it won't relay unless successfully connected
            if (addr.IsValid())
555
                addrman.Add(addr, CNetAddr("127.0.0.1"));
556
557
558
559
560
561
562
        }
    }

    if (mapArgs.count("-paytxfee"))
    {
        if (!ParseMoney(mapArgs["-paytxfee"], nTransactionFee))
        {
563
            ThreadSafeMessageBox(_("Invalid amount for -paytxfee=<amount>"), _("Bitcoin"), wxOK | wxMODAL);
564
565
566
            return false;
        }
        if (nTransactionFee > 0.25 * COIN)
567
            ThreadSafeMessageBox(_("Warning: -paytxfee is set very high.  This is the transaction fee you will pay if you send a transaction."), _("Bitcoin"), wxOK | wxICON_EXCLAMATION | wxMODAL);
568
569
570
    }

    //
Gavin Andresen's avatar
Gavin Andresen committed
571
    // Start the node
572
573
574
575
576
577
578
    //
    if (!CheckDiskSpace())
        return false;

    RandAddSeedPerfmon();

    if (!CreateThread(StartNode, NULL))
579
        ThreadSafeMessageBox(_("Error: CreateThread(StartNode) failed"), _("Bitcoin"), wxOK | wxMODAL);
580
581
582
583

    if (fServer)
        CreateThread(ThreadRPCServer, NULL);

584
585
586
587
588
#ifdef QT_GUI
    if(GetStartOnSystemStartup())
        SetStartOnSystemStartup(true); // Remove startup links to bitcoin-wx
#endif

Gavin Andresen's avatar
Gavin Andresen committed
589
#if !defined(QT_GUI)
590
591
592
593
594
595
    while (1)
        Sleep(5000);
#endif

    return true;
}
596