]> Git Repo - VerusCoin.git/blame - src/init.cpp
Allow binding to the any address, and report failure
[VerusCoin.git] / src / init.cpp
CommitLineData
69d605f4 1// Copyright (c) 2009-2010 Satoshi Nakamoto
88216419 2// Copyright (c) 2009-2012 The Bitcoin developers
69d605f4
WL
3// Distributed under the MIT/X11 software license, see the accompanying
4// file license.txt or http://www.opensource.org/licenses/mit-license.php.
0eeb4f5d 5#include "db.h"
9eace6b1 6#include "walletdb.h"
8fe2308b 7#include "bitcoinrpc.h"
0eeb4f5d
WL
8#include "net.h"
9#include "init.h"
ed6d0b5f
PW
10#include "util.h"
11#include "ui_interface.h"
e8ef3da7 12#include <boost/filesystem.hpp>
0eeb4f5d 13#include <boost/filesystem/fstream.hpp>
f18a119a 14#include <boost/filesystem/convenience.hpp>
0eeb4f5d 15#include <boost/interprocess/sync/file_lock.hpp>
69d605f4 16
ed6d0b5f
PW
17#ifndef WIN32
18#include <signal.h>
52d3a481 19#endif
5f2e76b8 20
69d605f4
WL
21using namespace std;
22using namespace boost;
23
e8ef3da7
WL
24CWallet* pwalletMain;
25
69d605f4
WL
26//////////////////////////////////////////////////////////////////////////////
27//
28// Shutdown
29//
30
31void ExitTimeout(void* parg)
32{
6853e627 33#ifdef WIN32
69d605f4
WL
34 Sleep(5000);
35 ExitProcess(0);
36#endif
37}
38
39void Shutdown(void* parg)
40{
41 static CCriticalSection cs_Shutdown;
42 static bool fTaken;
d764d916 43 bool fFirstThread = false;
69d605f4 44 {
f8dcd5ca
PW
45 TRY_LOCK(cs_Shutdown, lockShutdown);
46 if (lockShutdown)
47 {
48 fFirstThread = !fTaken;
49 fTaken = true;
50 }
69d605f4
WL
51 }
52 static bool fExit;
53 if (fFirstThread)
54 {
55 fShutdown = true;
56 nTransactionsUpdated++;
1c15f886 57 DBFlush(false);
69d605f4 58 StopNode();
1c15f886 59 DBFlush(true);
69d605f4 60 boost::filesystem::remove(GetPidFile());
e8ef3da7
WL
61 UnregisterWallet(pwalletMain);
62 delete pwalletMain;
69d605f4
WL
63 CreateThread(ExitTimeout, NULL);
64 Sleep(50);
65 printf("Bitcoin exiting\n\n");
66 fExit = true;
67 exit(0);
68 }
69 else
70 {
71 while (!fExit)
72 Sleep(500);
73 Sleep(100);
74 ExitThread(0);
75 }
76}
77
78void HandleSIGTERM(int)
79{
80 fRequestShutdown = true;
81}
82
83
84
85
86
87
88//////////////////////////////////////////////////////////////////////////////
89//
90// Start
91//
565c4771 92#if !defined(QT_GUI)
69d605f4
WL
93int main(int argc, char* argv[])
94{
95 bool fRet = false;
96 fRet = AppInit(argc, argv);
97
98 if (fRet && fDaemon)
99 return 0;
100
101 return 1;
102}
69d605f4
WL
103
104bool AppInit(int argc, char* argv[])
105{
106 bool fRet = false;
107 try
108 {
9f5b11e6
WL
109 //
110 // Parameters
111 //
112 // If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's main()
113 ParseParameters(argc, argv);
114 if (!boost::filesystem::is_directory(GetDataDir(false)))
115 {
116 fprintf(stderr, "Error: Specified directory does not exist\n");
117 Shutdown(NULL);
118 }
119 ReadConfigFile(mapArgs, mapMultiArgs);
120
121 if (mapArgs.count("-?") || mapArgs.count("--help"))
122 {
123 // First part of help message is specific to bitcoind / RPC client
124 std::string strUsage = _("Bitcoin version") + " " + FormatFullVersion() + "\n\n" +
125 _("Usage:") + "\n" +
126 " bitcoind [options] " + "\n" +
127 " bitcoind [options] <command> [params] " + _("Send command to -server or bitcoind") + "\n" +
128 " bitcoind [options] help " + _("List commands") + "\n" +
129 " bitcoind [options] help <command> " + _("Get help for a command") + "\n";
130
131 strUsage += "\n" + HelpMessage();
132
133 fprintf(stderr, "%s", strUsage.c_str());
134 return false;
135 }
136
137 // Command-line RPC
138 for (int i = 1; i < argc; i++)
139 if (!IsSwitchChar(argv[i][0]) && !(strlen(argv[i]) > 7 && strncasecmp(argv[i], "bitcoin:", 8) == 0))
140 fCommandLine = true;
141
142 if (fCommandLine)
143 {
144 int ret = CommandLineRPC(argc, argv);
145 exit(ret);
146 }
147
148 fRet = AppInit2();
69d605f4
WL
149 }
150 catch (std::exception& e) {
151 PrintException(&e, "AppInit()");
152 } catch (...) {
153 PrintException(NULL, "AppInit()");
154 }
155 if (!fRet)
156 Shutdown(NULL);
157 return fRet;
158}
9f5b11e6 159#endif
69d605f4 160
ac7c7ab9
PW
161bool static InitError(const std::string &str)
162{
163 ThreadSafeMessageBox(str, _("Bitcoin"), wxOK | wxMODAL);
164 return false;
165
166}
167
168bool static InitWarning(const std::string &str)
169{
170 ThreadSafeMessageBox(str, _("Bitcoin"), wxOK | wxICON_EXCLAMATION | wxMODAL);
171 return true;
172}
173
174
8f10a288
PW
175bool static Bind(const CService &addr) {
176 if (IsLimited(addr))
177 return false;
178 std::string strError;
179 if (!BindListenPort(addr, strError))
ac7c7ab9 180 return InitError(strError);
8f10a288
PW
181 return true;
182}
183
9f5b11e6
WL
184// Core-specific options shared between UI and daemon
185std::string HelpMessage()
186{
187 string strUsage = _("Options:") + "\n" +
188 " -conf=<file> " + _("Specify configuration file (default: bitcoin.conf)") + "\n" +
189 " -pid=<file> " + _("Specify pid file (default: bitcoind.pid)") + "\n" +
190 " -gen " + _("Generate coins") + "\n" +
191 " -gen=0 " + _("Don't generate coins") + "\n" +
192 " -datadir=<dir> " + _("Specify data directory") + "\n" +
193 " -dbcache=<n> " + _("Set database cache size in megabytes (default: 25)") + "\n" +
194 " -dblogsize=<n> " + _("Set database disk log size in megabytes (default: 100)") + "\n" +
195 " -timeout=<n> " + _("Specify connection timeout (in milliseconds)") + "\n" +
196 " -proxy=<ip:port> " + _("Connect through socks proxy") + "\n" +
197 " -socks=<n> " + _("Select the version of socks proxy to use (4 or 5, 5 is default)") + "\n" +
198 " -noproxy=<net> " + _("Do not use proxy for connections to network <net> (IPv4 or IPv6)") + "\n" +
199 " -dns " + _("Allow DNS lookups for -addnode, -seednode and -connect") + "\n" +
200 " -proxydns " + _("Pass DNS requests to (SOCKS5) proxy") + "\n" +
201 " -port=<port> " + _("Listen for connections on <port> (default: 8333 or testnet: 18333)") + "\n" +
202 " -maxconnections=<n> " + _("Maintain at most <n> connections to peers (default: 125)") + "\n" +
203 " -addnode=<ip> " + _("Add a node to connect to and attempt to keep the connection open") + "\n" +
204 " -connect=<ip> " + _("Connect only to the specified node") + "\n" +
205 " -seednode=<ip> " + _("Connect to a node to retrieve peer addresses, and disconnect") + "\n" +
206 " -externalip=<ip> " + _("Specify your own public address") + "\n" +
0f1707de 207 " -onlynet=<net> " + _("Only connect to nodes in network <net> (IPv4 or IPv6)") + "\n" +
9f5b11e6
WL
208 " -discover " + _("Try to discover public IP address (default: 1)") + "\n" +
209 " -irc " + _("Find peers using internet relay chat (default: 0)") + "\n" +
210 " -listen " + _("Accept connections from outside (default: 1)") + "\n" +
211 " -bind=<addr> " + _("Bind to given address. Use [host]:port notation for IPv6") + "\n" +
212 " -dnsseed " + _("Find peers using DNS lookup (default: 1)") + "\n" +
213 " -banscore=<n> " + _("Threshold for disconnecting misbehaving peers (default: 100)") + "\n" +
214 " -bantime=<n> " + _("Number of seconds to keep misbehaving peers from reconnecting (default: 86400)") + "\n" +
215 " -maxreceivebuffer=<n> " + _("Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000)") + "\n" +
216 " -maxsendbuffer=<n> " + _("Maximum per-connection send buffer, <n>*1000 bytes (default: 10000)") + "\n" +
217#ifdef USE_UPNP
218#if USE_UPNP
219 " -upnp " + _("Use Universal Plug and Play to map the listening port (default: 1)") + "\n" +
220#else
221 " -upnp " + _("Use Universal Plug and Play to map the listening port (default: 0)") + "\n" +
222#endif
223#endif
224 " -detachdb " + _("Detach block and address databases. Increases shutdown time (default: 0)") + "\n" +
225 " -paytxfee=<amt> " + _("Fee per KB to add to transactions you send") + "\n" +
226#ifdef QT_GUI
227 " -server " + _("Accept command line and JSON-RPC commands") + "\n" +
228#endif
229#if !defined(WIN32) && !defined(QT_GUI)
230 " -daemon " + _("Run in the background as a daemon and accept commands") + "\n" +
231#endif
232 " -testnet " + _("Use the test network") + "\n" +
233 " -debug " + _("Output extra debugging information") + "\n" +
234 " -logtimestamps " + _("Prepend debug output with timestamp") + "\n" +
235 " -printtoconsole " + _("Send trace/debug info to console instead of debug.log file") + "\n" +
236#ifdef WIN32
237 " -printtodebugger " + _("Send trace/debug info to debugger") + "\n" +
238#endif
239 " -rpcuser=<user> " + _("Username for JSON-RPC connections") + "\n" +
240 " -rpcpassword=<pw> " + _("Password for JSON-RPC connections") + "\n" +
241 " -rpcport=<port> " + _("Listen for JSON-RPC connections on <port> (default: 8332)") + "\n" +
242 " -rpcallowip=<ip> " + _("Allow JSON-RPC connections from specified IP address") + "\n" +
243 " -rpcconnect=<ip> " + _("Send commands to node running on <ip> (default: 127.0.0.1)") + "\n" +
244 " -blocknotify=<cmd> " + _("Execute command when the best block changes (%s in cmd is replaced by block hash)") + "\n" +
245 " -upgradewallet " + _("Upgrade wallet to latest format") + "\n" +
246 " -keypool=<n> " + _("Set key pool size to <n> (default: 100)") + "\n" +
247 " -rescan " + _("Rescan the block chain for missing wallet transactions") + "\n" +
248 " -checkblocks=<n> " + _("How many blocks to check at startup (default: 2500, 0 = all)") + "\n" +
249 " -checklevel=<n> " + _("How thorough the block verification is (0-6, default: 1)") + "\n" +
250 " -loadblock=<file> " + _("Imports blocks from external blk000?.dat file") + "\n" +
251 " -? " + _("This help message") + "\n";
252
253 strUsage += string() +
254 _("\nSSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n" +
255 " -rpcssl " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n" +
256 " -rpcsslcertificatechainfile=<file.cert> " + _("Server certificate file (default: server.cert)") + "\n" +
257 " -rpcsslprivatekeyfile=<file.pem> " + _("Server private key (default: server.pem)") + "\n" +
258 " -rpcsslciphers=<ciphers> " + _("Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)") + "\n";
259
260 return strUsage;
261}
262
263/** Initialize bitcoin.
264 * @pre Parameters should be parsed and config file should be read.
265 */
266bool AppInit2()
69d605f4
WL
267{
268#ifdef _MSC_VER
269 // Turn off microsoft heap dump noise
270 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
271 _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
272#endif
273#if _MSC_VER >= 1400
274 // Disable confusing "helpful" text message on abort, ctrl-c
275 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
276#endif
6853e627 277#ifndef WIN32
69d605f4
WL
278 umask(077);
279#endif
6853e627 280#ifndef WIN32
69d605f4
WL
281 // Clean shutdown on SIGTERM
282 struct sigaction sa;
283 sa.sa_handler = HandleSIGTERM;
284 sigemptyset(&sa.sa_mask);
285 sa.sa_flags = 0;
286 sigaction(SIGTERM, &sa, NULL);
287 sigaction(SIGINT, &sa, NULL);
288 sigaction(SIGHUP, &sa, NULL);
289#endif
290
8677f9c7 291 fTestNet = GetBoolArg("-testnet");
92d5864b
PW
292 if (fTestNet)
293 {
294 SoftSetBoolArg("-irc", true);
295 }
296
69d605f4 297 fDebug = GetBoolArg("-debug");
83743ed6 298 fDetachDB = GetBoolArg("-detachdb", false);
69d605f4 299
a3f3e54e 300#if !defined(WIN32) && !defined(QT_GUI)
69d605f4
WL
301 fDaemon = GetBoolArg("-daemon");
302#else
303 fDaemon = false;
304#endif
305
306 if (fDaemon)
307 fServer = true;
308 else
309 fServer = GetBoolArg("-server");
310
311 /* force fServer when running without GUI */
565c4771 312#if !defined(QT_GUI)
69d605f4 313 fServer = true;
858ff187 314#endif
69d605f4
WL
315 fPrintToConsole = GetBoolArg("-printtoconsole");
316 fPrintToDebugger = GetBoolArg("-printtodebugger");
69d605f4
WL
317 fLogTimestamps = GetBoolArg("-logtimestamps");
318
a3f3e54e 319#if !defined(WIN32) && !defined(QT_GUI)
69d605f4
WL
320 if (fDaemon)
321 {
322 // Daemonize
323 pid_t pid = fork();
324 if (pid < 0)
325 {
326 fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno);
327 return false;
328 }
329 if (pid > 0)
330 {
331 CreatePidFile(GetPidFile(), pid);
332 return true;
333 }
334
335 pid_t sid = setsid();
336 if (sid < 0)
337 fprintf(stderr, "Error: setsid() returned %d errno %d\n", sid, errno);
338 }
339#endif
340
ee12c3d6 341 if (!fDebug)
69d605f4
WL
342 ShrinkDebugFile();
343 printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
a20c0d0f 344 printf("Bitcoin version %s (%s)\n", FormatFullVersion().c_str(), CLIENT_DATE.c_str());
ee12c3d6 345 printf("Default data directory %s\n", GetDefaultDataDir().string().c_str());
69d605f4
WL
346
347 if (GetBoolArg("-loadblockindextest"))
348 {
349 CTxDB txdb("r");
350 txdb.LoadBlockIndex();
351 PrintBlockTree();
352 return false;
353 }
354
69d605f4 355 // Make sure only a single bitcoin process is using the data directory.
ee12c3d6
PW
356 boost::filesystem::path pathLockFile = GetDataDir() / ".lock";
357 FILE* file = fopen(pathLockFile.string().c_str(), "a"); // empty lock file; created if it doesn't exist.
69d605f4 358 if (file) fclose(file);
ee12c3d6 359 static boost::interprocess::file_lock lock(pathLockFile.string().c_str());
69d605f4 360 if (!lock.try_lock())
ac7c7ab9 361 return InitError(strprintf(_("Cannot obtain a lock on data directory %s. Bitcoin is probably already running."), GetDataDir().string().c_str()));
69d605f4 362
6e39e7c9 363 std::ostringstream strErrors;
69d605f4
WL
364 //
365 // Load data files
366 //
367 if (fDaemon)
368 fprintf(stdout, "bitcoin server starting\n");
bde280b9 369 int64 nStart;
69d605f4 370
3f0816e3 371 InitMessage(_("Loading addresses..."));
69d605f4
WL
372 printf("Loading addresses...\n");
373 nStart = GetTimeMillis();
374 if (!LoadAddresses())
6e39e7c9 375 strErrors << _("Error loading addr.dat") << "\n";
69d605f4
WL
376 printf(" addresses %15"PRI64d"ms\n", GetTimeMillis() - nStart);
377
3f0816e3 378 InitMessage(_("Loading block index..."));
69d605f4
WL
379 printf("Loading block index...\n");
380 nStart = GetTimeMillis();
381 if (!LoadBlockIndex())
6e39e7c9 382 strErrors << _("Error loading blkindex.dat") << "\n";
871c3557
B
383
384 // as LoadBlockIndex can take several minutes, it's possible the user
385 // requested to kill bitcoin-qt during the last operation. If so, exit.
386 // As the program has not fully started yet, Shutdown() is possibly overkill.
387 if (fRequestShutdown)
388 {
389 printf("Shutdown requested. Exiting.\n");
390 return false;
391 }
69d605f4
WL
392 printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart);
393
1d740055
PW
394 if (mapArgs.count("-loadblock"))
395 {
396 BOOST_FOREACH(string strFile, mapMultiArgs["-loadblock"])
397 {
398 FILE *file = fopen(strFile.c_str(), "rb");
399 if (file)
400 LoadExternalBlockFile(file);
401 }
402 }
403
3f0816e3 404 InitMessage(_("Loading wallet..."));
69d605f4
WL
405 printf("Loading wallet...\n");
406 nStart = GetTimeMillis();
407 bool fFirstRun;
e8ef3da7 408 pwalletMain = new CWallet("wallet.dat");
7ec55267
MC
409 int nLoadWalletRet = pwalletMain->LoadWallet(fFirstRun);
410 if (nLoadWalletRet != DB_LOAD_OK)
411 {
412 if (nLoadWalletRet == DB_CORRUPT)
6e39e7c9 413 strErrors << _("Error loading wallet.dat: Wallet corrupted") << "\n";
7ec55267 414 else if (nLoadWalletRet == DB_TOO_NEW)
6e39e7c9 415 strErrors << _("Error loading wallet.dat: Wallet requires newer version of Bitcoin") << "\n";
d764d916
GA
416 else if (nLoadWalletRet == DB_NEED_REWRITE)
417 {
6e39e7c9 418 strErrors << _("Wallet needed to be rewritten: restart Bitcoin to complete") << "\n";
21e875c9 419 printf("%s", strErrors.str().c_str());
ac7c7ab9 420 return InitError(strErrors.str());
d764d916 421 }
7ec55267 422 else
6e39e7c9 423 strErrors << _("Error loading wallet.dat") << "\n";
7ec55267 424 }
439e1497
PW
425
426 if (GetBoolArg("-upgradewallet", fFirstRun))
427 {
428 int nMaxVersion = GetArg("-upgradewallet", 0);
429 if (nMaxVersion == 0) // the -walletupgrade without argument case
430 {
431 printf("Performing wallet upgrade to %i\n", FEATURE_LATEST);
432 nMaxVersion = CLIENT_VERSION;
433 pwalletMain->SetMinVersion(FEATURE_LATEST); // permanently upgrade the wallet immediately
434 }
435 else
436 printf("Allowing wallet upgrade up to %i\n", nMaxVersion);
437 if (nMaxVersion < pwalletMain->GetVersion())
438 strErrors << _("Cannot downgrade wallet") << "\n";
439 pwalletMain->SetMaxVersion(nMaxVersion);
440 }
441
442 if (fFirstRun)
443 {
444 // Create new keyUser and set as default key
445 RandAddSeedPerfmon();
446
447 std::vector<unsigned char> newDefaultKey;
448 if (!pwalletMain->GetKeyFromPool(newDefaultKey, false))
449 strErrors << _("Cannot initialize keypool") << "\n";
450 pwalletMain->SetDefaultKey(newDefaultKey);
451 if (!pwalletMain->SetAddressBookName(CBitcoinAddress(pwalletMain->vchDefaultKey), ""))
452 strErrors << _("Cannot write default address") << "\n";
453 }
454
21e875c9 455 printf("%s", strErrors.str().c_str());
69d605f4
WL
456 printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart);
457
e8ef3da7
WL
458 RegisterWallet(pwalletMain);
459
69d605f4
WL
460 CBlockIndex *pindexRescan = pindexBest;
461 if (GetBoolArg("-rescan"))
462 pindexRescan = pindexGenesisBlock;
463 else
464 {
e8ef3da7 465 CWalletDB walletdb("wallet.dat");
69d605f4
WL
466 CBlockLocator locator;
467 if (walletdb.ReadBestBlock(locator))
468 pindexRescan = locator.GetBlockIndex();
469 }
470 if (pindexBest != pindexRescan)
471 {
3f0816e3 472 InitMessage(_("Rescanning..."));
69d605f4
WL
473 printf("Rescanning last %i blocks (from block %i)...\n", pindexBest->nHeight - pindexRescan->nHeight, pindexRescan->nHeight);
474 nStart = GetTimeMillis();
e8ef3da7 475 pwalletMain->ScanForWalletTransactions(pindexRescan, true);
69d605f4
WL
476 printf(" rescan %15"PRI64d"ms\n", GetTimeMillis() - nStart);
477 }
478
3f0816e3 479 InitMessage(_("Done loading"));
69d605f4
WL
480 printf("Done loading\n");
481
6e39e7c9
GA
482 //// debug print
483 printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size());
484 printf("nBestHeight = %d\n", nBestHeight);
485 printf("setKeyPool.size() = %d\n", pwalletMain->setKeyPool.size());
486 printf("mapWallet.size() = %d\n", pwalletMain->mapWallet.size());
487 printf("mapAddressBook.size() = %d\n", pwalletMain->mapAddressBook.size());
69d605f4 488
6e39e7c9 489 if (!strErrors.str().empty())
ac7c7ab9 490 return InitError(strErrors.str());
69d605f4
WL
491
492 // Add wallet transactions that aren't already in a block to mapTransactions
e8ef3da7 493 pwalletMain->ReacceptWalletTransactions();
69d605f4 494
0fcf91ea
GA
495 // Note: Bitcoin-QT stores several settings in the wallet, so we want
496 // to load the wallet BEFORE parsing command-line arguments, so
497 // the command-line/bitcoin.conf settings override GUI setting.
498
69d605f4
WL
499 //
500 // Parameters
501 //
502 if (GetBoolArg("-printblockindex") || GetBoolArg("-printblocktree"))
503 {
504 PrintBlockTree();
505 return false;
506 }
507
18cf2145
WL
508 if (mapArgs.count("-timeout"))
509 {
510 int nNewTimeout = GetArg("-timeout", 5000);
511 if (nNewTimeout > 0 && nNewTimeout < 600000)
512 nConnectTimeout = nNewTimeout;
513 }
514
69d605f4
WL
515 if (mapArgs.count("-printblock"))
516 {
517 string strMatch = mapArgs["-printblock"];
518 int nFound = 0;
519 for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
520 {
521 uint256 hash = (*mi).first;
522 if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0)
523 {
524 CBlockIndex* pindex = (*mi).second;
525 CBlock block;
526 block.ReadFromDisk(pindex);
527 block.BuildMerkleTree();
528 block.print();
529 printf("\n");
530 nFound++;
531 }
532 }
533 if (nFound == 0)
534 printf("No blocks matching %s were found\n", strMatch.c_str());
535 return false;
536 }
537
69d605f4
WL
538 if (mapArgs.count("-proxy"))
539 {
540 fUseProxy = true;
c981d768 541 addrProxy = CService(mapArgs["-proxy"], 9050);
69d605f4 542 if (!addrProxy.IsValid())
ac7c7ab9 543 return InitError(strprintf(_("Invalid -proxy address: '%s'"), mapArgs["-proxy"].c_str()));
69d605f4
WL
544 }
545
623b9878
PW
546 if (mapArgs.count("-noproxy"))
547 {
548 BOOST_FOREACH(std::string snet, mapMultiArgs["-noproxy"]) {
549 enum Network net = ParseNetwork(snet);
ac7c7ab9
PW
550 if (net == NET_UNROUTABLE)
551 return InitError(strprintf(_("Unknown network specified in -noproxy: '%s'"), snet.c_str()));
623b9878
PW
552 SetNoProxy(net);
553 }
554 }
555
19b6958c
PW
556 if (mapArgs.count("-connect"))
557 SoftSetBoolArg("-dnsseed", false);
8f10a288
PW
558
559 // even in Tor mode, if -bind is specified, you really want -listen
560 if (mapArgs.count("-bind"))
561 SoftSetBoolArg("-listen", true);
562
67a42f92 563 bool fTor = (fUseProxy && addrProxy.GetPort() == 9050);
0fcf91ea
GA
564 if (fTor)
565 {
7bf8b7c2 566 // Use SoftSetBoolArg here so user can override any of these if they wish.
0fcf91ea 567 // Note: the GetBoolArg() calls for all of these must happen later.
9d952d17
GA
568 SoftSetBoolArg("-listen", false);
569 SoftSetBoolArg("-irc", false);
9bab521d 570 SoftSetBoolArg("-proxydns", true);
7bf8b7c2 571 SoftSetBoolArg("-upnp", false);
19b6958c 572 SoftSetBoolArg("-discover", false);
0fcf91ea
GA
573 }
574
0f1707de
PW
575 if (mapArgs.count("-onlynet")) {
576 std::set<enum Network> nets;
577 BOOST_FOREACH(std::string snet, mapMultiArgs["-onlynet"]) {
457754d2 578 enum Network net = ParseNetwork(snet);
ac7c7ab9 579 if (net == NET_UNROUTABLE)
0f1707de
PW
580 return InitError(strprintf(_("Unknown network specified in -onlynet: '%s'"), snet.c_str()));
581 nets.insert(net);
582 }
583 for (int n = 0; n < NET_MAX; n++) {
584 enum Network net = (enum Network)n;
585 if (!nets.count(net))
586 SetLimited(net);
457754d2
PW
587 }
588 }
589
9bab521d
PW
590 fNameLookup = GetBoolArg("-dns");
591 fProxyNameLookup = GetBoolArg("-proxydns");
592 if (fProxyNameLookup)
593 fNameLookup = true;
9d952d17 594 fNoListen = !GetBoolArg("-listen", true);
9bab521d 595 nSocksVersion = GetArg("-socks", 5);
ac7c7ab9
PW
596 if (nSocksVersion != 4 && nSocksVersion != 5)
597 return InitError(strprintf(_("Unknown -socks proxy version requested: %i"), nSocksVersion));
0fcf91ea 598
478b01d9
PW
599 BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"])
600 AddOneShot(strDest);
0fcf91ea 601
8f188ece
GA
602 // Continue to put "/P2SH/" in the coinbase to monitor
603 // BIP16 support.
604 // This can be removed eventually...
605 const char* pszP2SH = "/P2SH/";
606 COINBASE_FLAGS << std::vector<unsigned char>(pszP2SH, pszP2SH+strlen(pszP2SH));
7bf8b7c2 607
8f10a288 608 bool fBound = false;
0fcf91ea
GA
609 if (!fNoListen)
610 {
611 std::string strError;
8f10a288
PW
612 if (mapArgs.count("-bind")) {
613 BOOST_FOREACH(std::string strBind, mapMultiArgs["-bind"]) {
55bb0cfb
PW
614 CService addrBind;
615 if (!Lookup(strBind.c_str(), addrBind, GetListenPort(), false))
ac7c7ab9
PW
616 return InitError(strprintf(_("Cannot resolve -bind address: '%s'"), strBind.c_str()));
617 fBound |= Bind(addrBind);
8f10a288
PW
618 }
619 } else {
839c4e79
PW
620 struct in_addr inaddr_any;
621 inaddr_any.s_addr = INADDR_ANY;
5a3cb32e 622 fBound |= Bind(CService(inaddr_any, GetListenPort()));
8f10a288 623#ifdef USE_IPV6
5a3cb32e 624 fBound |= Bind(CService(in6addr_any, GetListenPort()));
8f10a288 625#endif
0fcf91ea 626 }
8f10a288 627 if (!fBound)
55bb0cfb 628 return InitError(_("Not listening on any port"));
0fcf91ea
GA
629 }
630
19b6958c 631 if (mapArgs.count("-externalip"))
69d605f4 632 {
ac7c7ab9
PW
633 BOOST_FOREACH(string strAddr, mapMultiArgs["-externalip"]) {
634 CService addrLocal(strAddr, GetListenPort(), fNameLookup);
635 if (!addrLocal.IsValid())
636 return InitError(strprintf(_("Cannot resolve -externalip address: '%s'"), strAddr.c_str()));
5a3cb32e 637 AddLocal(CService(strAddr, GetListenPort(), fNameLookup), LOCAL_MANUAL);
ac7c7ab9 638 }
69d605f4
WL
639 }
640
69d605f4
WL
641 if (mapArgs.count("-paytxfee"))
642 {
643 if (!ParseMoney(mapArgs["-paytxfee"], nTransactionFee))
ac7c7ab9 644 return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s'"), mapArgs["-paytxfee"].c_str()));
69d605f4 645 if (nTransactionFee > 0.25 * COIN)
ac7c7ab9 646 InitWarning(_("Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction."));
69d605f4 647 }
69d605f4
WL
648
649 //
565c4771 650 // Start the node
69d605f4 651 //
69d605f4
WL
652 if (!CheckDiskSpace())
653 return false;
654
655 RandAddSeedPerfmon();
656
657 if (!CreateThread(StartNode, NULL))
ac7c7ab9 658 InitError(_("Error: could not start node"));
69d605f4
WL
659
660 if (fServer)
661 CreateThread(ThreadRPCServer, NULL);
662
565c4771 663#if !defined(QT_GUI)
9f5b11e6
WL
664 // Loop until process is exit()ed from shutdown() function,
665 // called from ThreadRPCServer thread when a "stop" command is received.
69d605f4
WL
666 while (1)
667 Sleep(5000);
668#endif
669
670 return true;
671}
f18a119a 672
This page took 0.205094 seconds and 4 git commands to generate.