You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

init.cpp 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  1. // Copyright (c) 2009-2010 Satoshi Nakamoto
  2. // Distributed under the MIT/X11 software license, see the accompanying
  3. // file license.txt or http://www.opensource.org/licenses/mit-license.php.
  4. #include "headers.h"
  5. using namespace std;
  6. using namespace boost;
  7. //////////////////////////////////////////////////////////////////////////////
  8. //
  9. // Shutdown
  10. //
  11. void ExitTimeout(void* parg)
  12. {
  13. #ifdef __WXMSW__
  14. Sleep(5000);
  15. ExitProcess(0);
  16. #endif
  17. }
  18. void Shutdown(void* parg)
  19. {
  20. static CCriticalSection cs_Shutdown;
  21. static bool fTaken;
  22. bool fFirstThread;
  23. CRITICAL_BLOCK(cs_Shutdown)
  24. {
  25. fFirstThread = !fTaken;
  26. fTaken = true;
  27. }
  28. static bool fExit;
  29. if (fFirstThread)
  30. {
  31. fShutdown = true;
  32. nTransactionsUpdated++;
  33. DBFlush(false);
  34. StopNode();
  35. DBFlush(true);
  36. boost::filesystem::remove(GetPidFile());
  37. CreateThread(ExitTimeout, NULL);
  38. Sleep(50);
  39. printf("Bitcoin exiting\n\n");
  40. fExit = true;
  41. exit(0);
  42. }
  43. else
  44. {
  45. while (!fExit)
  46. Sleep(500);
  47. Sleep(100);
  48. ExitThread(0);
  49. }
  50. }
  51. void HandleSIGTERM(int)
  52. {
  53. fRequestShutdown = true;
  54. }
  55. //////////////////////////////////////////////////////////////////////////////
  56. //
  57. // Start
  58. //
  59. #ifndef GUI
  60. int main(int argc, char* argv[])
  61. {
  62. bool fRet = false;
  63. fRet = AppInit(argc, argv);
  64. if (fRet && fDaemon)
  65. return 0;
  66. return 1;
  67. }
  68. #endif
  69. bool AppInit(int argc, char* argv[])
  70. {
  71. bool fRet = false;
  72. try
  73. {
  74. fRet = AppInit2(argc, argv);
  75. }
  76. catch (std::exception& e) {
  77. PrintException(&e, "AppInit()");
  78. } catch (...) {
  79. PrintException(NULL, "AppInit()");
  80. }
  81. if (!fRet)
  82. Shutdown(NULL);
  83. return fRet;
  84. }
  85. bool AppInit2(int argc, char* argv[])
  86. {
  87. #ifdef _MSC_VER
  88. // Turn off microsoft heap dump noise
  89. _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
  90. _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
  91. #endif
  92. #if _MSC_VER >= 1400
  93. // Disable confusing "helpful" text message on abort, ctrl-c
  94. _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
  95. #endif
  96. #ifndef __WXMSW__
  97. umask(077);
  98. #endif
  99. #ifndef __WXMSW__
  100. // Clean shutdown on SIGTERM
  101. struct sigaction sa;
  102. sa.sa_handler = HandleSIGTERM;
  103. sigemptyset(&sa.sa_mask);
  104. sa.sa_flags = 0;
  105. sigaction(SIGTERM, &sa, NULL);
  106. sigaction(SIGINT, &sa, NULL);
  107. sigaction(SIGHUP, &sa, NULL);
  108. #endif
  109. //
  110. // Parameters
  111. //
  112. ParseParameters(argc, argv);
  113. if (mapArgs.count("-datadir"))
  114. {
  115. filesystem::path pathDataDir = filesystem::system_complete(mapArgs["-datadir"]);
  116. strlcpy(pszSetDataDir, pathDataDir.string().c_str(), sizeof(pszSetDataDir));
  117. }
  118. ReadConfigFile(mapArgs, mapMultiArgs); // Must be done after processing datadir
  119. if (mapArgs.count("-?") || mapArgs.count("--help"))
  120. {
  121. string beta = VERSION_IS_BETA ? _(" beta") : "";
  122. string strUsage = string() +
  123. _("Bitcoin version") + " " + FormatFullVersion() + "\n\n" +
  124. _("Usage:") + "\t\t\t\t\t\t\t\t\t\t\n" +
  125. " bitcoin [options] \t " + "\n" +
  126. " bitcoin [options] <command> [params]\t " + _("Send command to -server or bitcoind\n") +
  127. " bitcoin [options] help \t\t " + _("List commands\n") +
  128. " bitcoin [options] help <command> \t\t " + _("Get help for a command\n") +
  129. _("Options:\n") +
  130. " -conf=<file> \t\t " + _("Specify configuration file (default: bitcoin.conf)\n") +
  131. " -pid=<file> \t\t " + _("Specify pid file (default: bitcoind.pid)\n") +
  132. " -gen \t\t " + _("Generate coins\n") +
  133. " -gen=0 \t\t " + _("Don't generate coins\n") +
  134. " -min \t\t " + _("Start minimized\n") +
  135. " -datadir=<dir> \t\t " + _("Specify data directory\n") +
  136. " -proxy=<ip:port> \t " + _("Connect through socks4 proxy\n") +
  137. " -dns \t " + _("Allow DNS lookups for addnode and connect\n") +
  138. " -addnode=<ip> \t " + _("Add a node to connect to\n") +
  139. " -connect=<ip> \t\t " + _("Connect only to the specified node\n") +
  140. " -nolisten \t " + _("Don't accept connections from outside\n") +
  141. #ifdef USE_UPNP
  142. #if USE_UPNP
  143. " -noupnp \t " + _("Don't attempt to use UPnP to map the listening port\n") +
  144. #else
  145. " -upnp \t " + _("Attempt to use UPnP to map the listening port\n") +
  146. #endif
  147. #endif
  148. " -paytxfee=<amt> \t " + _("Fee per KB to add to transactions you send\n") +
  149. #ifdef GUI
  150. " -server \t\t " + _("Accept command line and JSON-RPC commands\n") +
  151. #endif
  152. #ifndef __WXMSW__
  153. " -daemon \t\t " + _("Run in the background as a daemon and accept commands\n") +
  154. #endif
  155. " -testnet \t\t " + _("Use the test network\n") +
  156. " -rpcuser=<user> \t " + _("Username for JSON-RPC connections\n") +
  157. " -rpcpassword=<pw>\t " + _("Password for JSON-RPC connections\n") +
  158. " -rpcport=<port> \t\t " + _("Listen for JSON-RPC connections on <port> (default: 8332)\n") +
  159. " -rpcallowip=<ip> \t\t " + _("Allow JSON-RPC connections from specified IP address\n") +
  160. " -rpcconnect=<ip> \t " + _("Send commands to node running on <ip> (default: 127.0.0.1)\n") +
  161. " -keypool=<n> \t " + _("Set key pool size to <n> (default: 100)\n") +
  162. " -rescan \t " + _("Rescan the block chain for missing wallet transactions\n");
  163. #ifdef USE_SSL
  164. strUsage += string() +
  165. _("\nSSL options: (see the Bitcoin Wiki for SSL setup instructions)\n") +
  166. " -rpcssl \t " + _("Use OpenSSL (https) for JSON-RPC connections\n") +
  167. " -rpcsslcertificatechainfile=<file.cert>\t " + _("Server certificate file (default: server.cert)\n") +
  168. " -rpcsslprivatekeyfile=<file.pem> \t " + _("Server private key (default: server.pem)\n") +
  169. " -rpcsslciphers=<ciphers> \t " + _("Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)\n");
  170. #endif
  171. strUsage += string() +
  172. " -? \t\t " + _("This help message\n");
  173. #if defined(__WXMSW__) && defined(GUI)
  174. // Tabs make the columns line up in the message box
  175. wxMessageBox(strUsage, "Bitcoin", wxOK);
  176. #else
  177. // Remove tabs
  178. strUsage.erase(std::remove(strUsage.begin(), strUsage.end(), '\t'), strUsage.end());
  179. fprintf(stderr, "%s", strUsage.c_str());
  180. #endif
  181. return false;
  182. }
  183. fDebug = GetBoolArg("-debug");
  184. fAllowDNS = GetBoolArg("-dns");
  185. #ifndef __WXMSW__
  186. fDaemon = GetBoolArg("-daemon");
  187. #else
  188. fDaemon = false;
  189. #endif
  190. if (fDaemon)
  191. fServer = true;
  192. else
  193. fServer = GetBoolArg("-server");
  194. /* force fServer when running without GUI */
  195. #ifndef GUI
  196. fServer = true;
  197. #endif
  198. fPrintToConsole = GetBoolArg("-printtoconsole");
  199. fPrintToDebugger = GetBoolArg("-printtodebugger");
  200. fTestNet = GetBoolArg("-testnet");
  201. fNoListen = GetBoolArg("-nolisten");
  202. fLogTimestamps = GetBoolArg("-logtimestamps");
  203. for (int i = 1; i < argc; i++)
  204. if (!IsSwitchChar(argv[i][0]))
  205. fCommandLine = true;
  206. if (fCommandLine)
  207. {
  208. int ret = CommandLineRPC(argc, argv);
  209. exit(ret);
  210. }
  211. #ifndef __WXMSW__
  212. if (fDaemon)
  213. {
  214. // Daemonize
  215. pid_t pid = fork();
  216. if (pid < 0)
  217. {
  218. fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno);
  219. return false;
  220. }
  221. if (pid > 0)
  222. {
  223. CreatePidFile(GetPidFile(), pid);
  224. return true;
  225. }
  226. pid_t sid = setsid();
  227. if (sid < 0)
  228. fprintf(stderr, "Error: setsid() returned %d errno %d\n", sid, errno);
  229. }
  230. #endif
  231. if (!fDebug && !pszSetDataDir[0])
  232. ShrinkDebugFile();
  233. printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
  234. printf("Bitcoin version %s\n", FormatFullVersion().c_str());
  235. #ifdef GUI
  236. printf("OS version %s\n", ((string)wxGetOsDescription()).c_str());
  237. printf("System default language is %d %s\n", g_locale.GetSystemLanguage(), ((string)g_locale.GetSysName()).c_str());
  238. printf("Language file %s (%s)\n", (string("locale/") + (string)g_locale.GetCanonicalName() + "/LC_MESSAGES/bitcoin.mo").c_str(), ((string)g_locale.GetLocale()).c_str());
  239. #endif
  240. printf("Default data directory %s\n", GetDefaultDataDir().c_str());
  241. if (GetBoolArg("-loadblockindextest"))
  242. {
  243. CTxDB txdb("r");
  244. txdb.LoadBlockIndex();
  245. PrintBlockTree();
  246. return false;
  247. }
  248. //
  249. // Limit to single instance per user
  250. // Required to protect the database files if we're going to keep deleting log.*
  251. //
  252. #if defined(__WXMSW__) && defined(GUI)
  253. // wxSingleInstanceChecker doesn't work on Linux
  254. wxString strMutexName = wxString("bitcoin_running.") + getenv("HOMEPATH");
  255. for (int i = 0; i < strMutexName.size(); i++)
  256. if (!isalnum(strMutexName[i]))
  257. strMutexName[i] = '.';
  258. wxSingleInstanceChecker* psingleinstancechecker = new wxSingleInstanceChecker(strMutexName);
  259. if (psingleinstancechecker->IsAnotherRunning())
  260. {
  261. printf("Existing instance found\n");
  262. unsigned int nStart = GetTime();
  263. loop
  264. {
  265. // Show the previous instance and exit
  266. HWND hwndPrev = FindWindowA("wxWindowClassNR", "Bitcoin");
  267. if (hwndPrev)
  268. {
  269. if (IsIconic(hwndPrev))
  270. ShowWindow(hwndPrev, SW_RESTORE);
  271. SetForegroundWindow(hwndPrev);
  272. return false;
  273. }
  274. if (GetTime() > nStart + 60)
  275. return false;
  276. // Resume this instance if the other exits
  277. delete psingleinstancechecker;
  278. Sleep(1000);
  279. psingleinstancechecker = new wxSingleInstanceChecker(strMutexName);
  280. if (!psingleinstancechecker->IsAnotherRunning())
  281. break;
  282. }
  283. }
  284. #endif
  285. // Make sure only a single bitcoin process is using the data directory.
  286. string strLockFile = GetDataDir() + "/.lock";
  287. FILE* file = fopen(strLockFile.c_str(), "a"); // empty lock file; created if it doesn't exist.
  288. if (file) fclose(file);
  289. static boost::interprocess::file_lock lock(strLockFile.c_str());
  290. if (!lock.try_lock())
  291. {
  292. wxMessageBox(strprintf(_("Cannot obtain a lock on data directory %s. Bitcoin is probably already running."), GetDataDir().c_str()), "Bitcoin");
  293. return false;
  294. }
  295. // Bind to the port early so we can tell if another instance is already running.
  296. string strErrors;
  297. if (!fNoListen)
  298. {
  299. if (!BindListenPort(strErrors))
  300. {
  301. wxMessageBox(strErrors, "Bitcoin");
  302. return false;
  303. }
  304. }
  305. //
  306. // Load data files
  307. //
  308. if (fDaemon)
  309. fprintf(stdout, "bitcoin server starting\n");
  310. strErrors = "";
  311. int64 nStart;
  312. printf("Loading addresses...\n");
  313. nStart = GetTimeMillis();
  314. if (!LoadAddresses())
  315. strErrors += _("Error loading addr.dat \n");
  316. printf(" addresses %15"PRI64d"ms\n", GetTimeMillis() - nStart);
  317. printf("Loading block index...\n");
  318. nStart = GetTimeMillis();
  319. if (!LoadBlockIndex())
  320. strErrors += _("Error loading blkindex.dat \n");
  321. printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart);
  322. printf("Loading wallet...\n");
  323. nStart = GetTimeMillis();
  324. bool fFirstRun;
  325. if (!LoadWallet(fFirstRun))
  326. strErrors += _("Error loading wallet.dat \n");
  327. printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart);
  328. CBlockIndex *pindexRescan = pindexBest;
  329. if (GetBoolArg("-rescan"))
  330. pindexRescan = pindexGenesisBlock;
  331. else
  332. {
  333. CWalletDB walletdb;
  334. CBlockLocator locator;
  335. if (walletdb.ReadBestBlock(locator))
  336. pindexRescan = locator.GetBlockIndex();
  337. }
  338. if (pindexBest != pindexRescan)
  339. {
  340. printf("Rescanning last %i blocks (from block %i)...\n", pindexBest->nHeight - pindexRescan->nHeight, pindexRescan->nHeight);
  341. nStart = GetTimeMillis();
  342. ScanForWalletTransactions(pindexRescan);
  343. printf(" rescan %15"PRI64d"ms\n", GetTimeMillis() - nStart);
  344. }
  345. printf("Done loading\n");
  346. //// debug print
  347. printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size());
  348. printf("nBestHeight = %d\n", nBestHeight);
  349. printf("mapKeys.size() = %d\n", mapKeys.size());
  350. printf("mapPubKeys.size() = %d\n", mapPubKeys.size());
  351. printf("mapWallet.size() = %d\n", mapWallet.size());
  352. printf("mapAddressBook.size() = %d\n", mapAddressBook.size());
  353. if (!strErrors.empty())
  354. {
  355. wxMessageBox(strErrors, "Bitcoin", wxOK | wxICON_ERROR);
  356. return false;
  357. }
  358. // Add wallet transactions that aren't already in a block to mapTransactions
  359. ReacceptWalletTransactions();
  360. //
  361. // Parameters
  362. //
  363. if (GetBoolArg("-printblockindex") || GetBoolArg("-printblocktree"))
  364. {
  365. PrintBlockTree();
  366. return false;
  367. }
  368. if (mapArgs.count("-printblock"))
  369. {
  370. string strMatch = mapArgs["-printblock"];
  371. int nFound = 0;
  372. for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
  373. {
  374. uint256 hash = (*mi).first;
  375. if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0)
  376. {
  377. CBlockIndex* pindex = (*mi).second;
  378. CBlock block;
  379. block.ReadFromDisk(pindex);
  380. block.BuildMerkleTree();
  381. block.print();
  382. printf("\n");
  383. nFound++;
  384. }
  385. }
  386. if (nFound == 0)
  387. printf("No blocks matching %s were found\n", strMatch.c_str());
  388. return false;
  389. }
  390. fGenerateBitcoins = GetBoolArg("-gen");
  391. if (mapArgs.count("-proxy"))
  392. {
  393. fUseProxy = true;
  394. addrProxy = CAddress(mapArgs["-proxy"]);
  395. if (!addrProxy.IsValid())
  396. {
  397. wxMessageBox(_("Invalid -proxy address"), "Bitcoin");
  398. return false;
  399. }
  400. }
  401. if (mapArgs.count("-addnode"))
  402. {
  403. BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
  404. {
  405. CAddress addr(strAddr, fAllowDNS);
  406. addr.nTime = 0; // so it won't relay unless successfully connected
  407. if (addr.IsValid())
  408. AddAddress(addr);
  409. }
  410. }
  411. if (mapArgs.count("-dnsseed"))
  412. DNSAddressSeed();
  413. if (mapArgs.count("-paytxfee"))
  414. {
  415. if (!ParseMoney(mapArgs["-paytxfee"], nTransactionFee))
  416. {
  417. wxMessageBox(_("Invalid amount for -paytxfee=<amount>"), "Bitcoin");
  418. return false;
  419. }
  420. if (nTransactionFee > 0.25 * COIN)
  421. wxMessageBox(_("Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction."), "Bitcoin", wxOK | wxICON_EXCLAMATION);
  422. }
  423. if (fHaveUPnP)
  424. {
  425. #if USE_UPNP
  426. if (GetBoolArg("-noupnp"))
  427. fUseUPnP = false;
  428. #else
  429. if (GetBoolArg("-upnp"))
  430. fUseUPnP = true;
  431. #endif
  432. }
  433. //
  434. // Create the main window and start the node
  435. //
  436. #ifdef GUI
  437. if (!fDaemon)
  438. CreateMainWindow();
  439. #endif
  440. if (!CheckDiskSpace())
  441. return false;
  442. RandAddSeedPerfmon();
  443. if (!CreateThread(StartNode, NULL))
  444. wxMessageBox("Error: CreateThread(StartNode) failed", "Bitcoin");
  445. if (fServer)
  446. CreateThread(ThreadRPCServer, NULL);
  447. #if defined(__WXMSW__) && defined(GUI)
  448. if (fFirstRun)
  449. SetStartOnSystemStartup(true);
  450. #endif
  451. #ifndef GUI
  452. while (1)
  453. Sleep(5000);
  454. #endif
  455. return true;
  456. }