]> Git Repo - VerusCoin.git/blame - src/init.cpp
Merge pull request #2781 from sipa/keytimemem
[VerusCoin.git] / src / init.cpp
CommitLineData
69d605f4 1// Copyright (c) 2009-2010 Satoshi Nakamoto
88216419 2// Copyright (c) 2009-2012 The Bitcoin developers
69d605f4 3// Distributed under the MIT/X11 software license, see the accompanying
3a25a2b9 4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5350ea41 5
663224c2
EL
6#include "init.h"
7#include "main.h"
05df3fc6 8#include "core.h"
2d8a4829 9#include "txdb.h"
9eace6b1 10#include "walletdb.h"
8fe2308b 11#include "bitcoinrpc.h"
0eeb4f5d 12#include "net.h"
ed6d0b5f
PW
13#include "util.h"
14#include "ui_interface.h"
f0d8a52c 15#include "checkpoints.h"
5350ea41 16
e8ef3da7 17#include <boost/filesystem.hpp>
0eeb4f5d 18#include <boost/filesystem/fstream.hpp>
f18a119a 19#include <boost/filesystem/convenience.hpp>
0eeb4f5d 20#include <boost/interprocess/sync/file_lock.hpp>
00fb0815 21#include <boost/algorithm/string/predicate.hpp>
31b581bc 22#include <openssl/crypto.h>
69d605f4 23
ed6d0b5f
PW
24#ifndef WIN32
25#include <signal.h>
52d3a481 26#endif
5f2e76b8 27
69d605f4
WL
28using namespace std;
29using namespace boost;
30
e8ef3da7 31CWallet* pwalletMain;
ab1b288f 32CClientUIInterface uiInterface;
e8ef3da7 33
ba29a559
PW
34#ifdef WIN32
35// Win32 LevelDB doesn't use filedescriptors, and the ones used for
36// accessing block files, don't count towards to fd_set size limit
37// anyway.
38#define MIN_CORE_FILEDESCRIPTORS 0
39#else
40#define MIN_CORE_FILEDESCRIPTORS 150
41#endif
42
c73323ee
PK
43// Used to pass flags to the Bind() function
44enum BindFlags {
29e214aa
PK
45 BF_NONE = 0,
46 BF_EXPLICIT = (1U << 0),
47 BF_REPORT_ERROR = (1U << 1)
c73323ee
PK
48};
49
4751d07e 50
69d605f4
WL
51//////////////////////////////////////////////////////////////////////////////
52//
53// Shutdown
54//
55
b31499ec
GA
56//
57// Thread management and startup/shutdown:
58//
59// The network-processing threads are all part of a thread group
60// created by AppInit() or the Qt main() function.
61//
62// A clean exit happens when StartShutdown() or the SIGTERM
63// signal handler sets fRequestShutdown, which triggers
64// the DetectShutdownThread(), which interrupts the main thread group.
65// DetectShutdownThread() then exits, which causes AppInit() to
66// continue (it .joins the shutdown thread).
67// Shutdown() is then
68// called to clean up database connections, and stop other
69// threads that should only be stopped after the main network-processing
70// threads have exited.
71//
72// Note that if running -daemon the parent process returns from AppInit2
73// before adding any threads to the threadGroup, so .join_all() returns
74// immediately and the parent exits from main().
75//
76// Shutdown for Qt is very similar, only it uses a QTimer to detect
723035bb
GA
77// fRequestShutdown getting set, and then does the normal Qt
78// shutdown thing.
b31499ec
GA
79//
80
81volatile bool fRequestShutdown = false;
69d605f4 82
9247134e
PK
83void StartShutdown()
84{
b31499ec 85 fRequestShutdown = true;
9247134e 86}
723035bb
GA
87bool ShutdownRequested()
88{
89 return fRequestShutdown;
90}
9247134e 91
ae8bfd12
PW
92static CCoinsViewDB *pcoinsdbview;
93
b31499ec 94void Shutdown()
69d605f4
WL
95{
96 static CCriticalSection cs_Shutdown;
b31499ec
GA
97 TRY_LOCK(cs_Shutdown, lockShutdown);
98 if (!lockShutdown) return;
96931d6f 99
96931d6f 100 RenameThread("bitcoin-shutoff");
21eb5ada
GA
101 nTransactionsUpdated++;
102 StopRPCThreads();
d98bf10f 103 ShutdownRPCMining();
21eb5ada 104 bitdb.Flush(false);
4751d07e 105 GenerateBitcoins(false, NULL);
21eb5ada 106 StopNode();
69d605f4 107 {
b31499ec 108 LOCK(cs_main);
dbc6dea1
GA
109 if (pwalletMain)
110 pwalletMain->SetBestChain(CBlockLocator(pindexBest));
b31499ec
GA
111 if (pblocktree)
112 pblocktree->Flush();
113 if (pcoinsTip)
114 pcoinsTip->Flush();
115 delete pcoinsTip; pcoinsTip = NULL;
116 delete pcoinsdbview; pcoinsdbview = NULL;
117 delete pblocktree; pblocktree = NULL;
69d605f4 118 }
b31499ec
GA
119 bitdb.Flush(true);
120 boost::filesystem::remove(GetPidFile());
121 UnregisterWallet(pwalletMain);
122 delete pwalletMain;
69d605f4
WL
123}
124
c8c2fbe0
GA
125//
126// Signal handlers are very limited in what they are allowed to do, so:
127//
69d605f4
WL
128void HandleSIGTERM(int)
129{
130 fRequestShutdown = true;
131}
132
9af080c3
MH
133void HandleSIGHUP(int)
134{
135 fReopenDebugLog = true;
136}
69d605f4 137
ac7c7ab9
PW
138bool static InitError(const std::string &str)
139{
5350ea41 140 uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_ERROR);
ac7c7ab9 141 return false;
ac7c7ab9
PW
142}
143
144bool static InitWarning(const std::string &str)
145{
5350ea41 146 uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_WARNING);
ac7c7ab9
PW
147 return true;
148}
149
29e214aa 150bool static Bind(const CService &addr, unsigned int flags) {
c73323ee 151 if (!(flags & BF_EXPLICIT) && IsLimited(addr))
8f10a288
PW
152 return false;
153 std::string strError;
587f929c 154 if (!BindListenPort(addr, strError)) {
c73323ee 155 if (flags & BF_REPORT_ERROR)
587f929c
PW
156 return InitError(strError);
157 return false;
158 }
8f10a288
PW
159 return true;
160}
161
9f5b11e6
WL
162// Core-specific options shared between UI and daemon
163std::string HelpMessage()
164{
c98c88b3
CF
165 string strUsage = _("Options:") + "\n";
166 strUsage += " -? " + _("This help message") + "\n";
167 strUsage += " -conf=<file> " + _("Specify configuration file (default: bitcoin.conf)") + "\n";
168 strUsage += " -pid=<file> " + _("Specify pid file (default: bitcoind.pid)") + "\n";
169 strUsage += " -gen " + _("Generate coins (default: 0)") + "\n";
170 strUsage += " -datadir=<dir> " + _("Specify data directory") + "\n";
171 strUsage += " -dbcache=<n> " + _("Set database cache size in megabytes (default: 25)") + "\n";
172 strUsage += " -timeout=<n> " + _("Specify connection timeout in milliseconds (default: 5000)") + "\n";
173 strUsage += " -proxy=<ip:port> " + _("Connect through socks proxy") + "\n";
174 strUsage += " -socks=<n> " + _("Select the version of socks proxy to use (4-5, default: 5)") + "\n";
175 strUsage += " -tor=<ip:port> " + _("Use proxy to reach tor hidden services (default: same as -proxy)") + "\n";
176 strUsage += " -dns " + _("Allow DNS lookups for -addnode, -seednode and -connect") + "\n";
177 strUsage += " -port=<port> " + _("Listen for connections on <port> (default: 8333 or testnet: 18333)") + "\n";
178 strUsage += " -maxconnections=<n> " + _("Maintain at most <n> connections to peers (default: 125)") + "\n";
179 strUsage += " -addnode=<ip> " + _("Add a node to connect to and attempt to keep the connection open") + "\n";
180 strUsage += " -connect=<ip> " + _("Connect only to the specified node(s)") + "\n";
181 strUsage += " -seednode=<ip> " + _("Connect to a node to retrieve peer addresses, and disconnect") + "\n";
182 strUsage += " -externalip=<ip> " + _("Specify your own public address") + "\n";
183 strUsage += " -onlynet=<net> " + _("Only connect to nodes in network <net> (IPv4, IPv6 or Tor)") + "\n";
184 strUsage += " -discover " + _("Discover own IP address (default: 1 when listening and no -externalip)") + "\n";
185 strUsage += " -checkpoints " + _("Only accept block chain matching built-in checkpoints (default: 1)") + "\n";
186 strUsage += " -listen " + _("Accept connections from outside (default: 1 if no -proxy or -connect)") + "\n";
187 strUsage += " -bind=<addr> " + _("Bind to given address and always listen on it. Use [host]:port notation for IPv6") + "\n";
188 strUsage += " -dnsseed " + _("Find peers using DNS lookup (default: 1 unless -connect)") + "\n";
189 strUsage += " -banscore=<n> " + _("Threshold for disconnecting misbehaving peers (default: 100)") + "\n";
190 strUsage += " -bantime=<n> " + _("Number of seconds to keep misbehaving peers from reconnecting (default: 86400)") + "\n";
191 strUsage += " -maxreceivebuffer=<n> " + _("Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)") + "\n";
192 strUsage += " -maxsendbuffer=<n> " + _("Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)") + "\n";
9f5b11e6
WL
193#ifdef USE_UPNP
194#if USE_UPNP
c98c88b3 195 strUsage += " -upnp " + _("Use UPnP to map the listening port (default: 1 when listening)") + "\n";
9f5b11e6 196#else
c98c88b3 197 strUsage += " -upnp " + _("Use UPnP to map the listening port (default: 0)") + "\n";
9f5b11e6
WL
198#endif
199#endif
c98c88b3 200 strUsage += " -paytxfee=<amt> " + _("Fee per KB to add to transactions you send") + "\n";
7f61f1ac
CF
201 if (fHaveGUI)
202 strUsage += " -server " + _("Accept command line and JSON-RPC commands") + "\n";
203#if !defined(WIN32)
204 if (fHaveGUI)
205 strUsage += " -daemon " + _("Run in the background as a daemon and accept commands") + "\n";
9f5b11e6 206#endif
c98c88b3
CF
207 strUsage += " -testnet " + _("Use the test network") + "\n";
208 strUsage += " -debug " + _("Output extra debugging information. Implies all other -debug* options") + "\n";
209 strUsage += " -debugnet " + _("Output extra network debugging information") + "\n";
210 strUsage += " -logtimestamps " + _("Prepend debug output with timestamp") + "\n";
211 strUsage += " -shrinkdebugfile " + _("Shrink debug.log file on client startup (default: 1 when no -debug)") + "\n";
212 strUsage += " -printtoconsole " + _("Send trace/debug info to console instead of debug.log file") + "\n";
9f5b11e6 213#ifdef WIN32
c98c88b3 214 strUsage += " -printtodebugger " + _("Send trace/debug info to debugger") + "\n";
9f5b11e6 215#endif
c98c88b3
CF
216 strUsage += " -rpcuser=<user> " + _("Username for JSON-RPC connections") + "\n";
217 strUsage += " -rpcpassword=<pw> " + _("Password for JSON-RPC connections") + "\n";
218 strUsage += " -rpcport=<port> " + _("Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)") + "\n";
219 strUsage += " -rpcallowip=<ip> " + _("Allow JSON-RPC connections from specified IP address") + "\n";
7f61f1ac
CF
220 if (!fHaveGUI)
221 strUsage += " -rpcconnect=<ip> " + _("Send commands to node running on <ip> (default: 127.0.0.1)") + "\n";
c98c88b3
CF
222 strUsage += " -rpcthreads=<n> " + _("Set the number of threads to service RPC calls (default: 4)") + "\n";
223 strUsage += " -blocknotify=<cmd> " + _("Execute command when the best block changes (%s in cmd is replaced by block hash)") + "\n";
224 strUsage += " -walletnotify=<cmd> " + _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)") + "\n";
225 strUsage += " -alertnotify=<cmd> " + _("Execute command when a relevant alert is received (%s in cmd is replaced by message)") + "\n";
226 strUsage += " -upgradewallet " + _("Upgrade wallet to latest format") + "\n";
227 strUsage += " -keypool=<n> " + _("Set key pool size to <n> (default: 100)") + "\n";
228 strUsage += " -rescan " + _("Rescan the block chain for missing wallet transactions") + "\n";
229 strUsage += " -salvagewallet " + _("Attempt to recover private keys from a corrupt wallet.dat") + "\n";
230 strUsage += " -checkblocks=<n> " + _("How many blocks to check at startup (default: 288, 0 = all)") + "\n";
231 strUsage += " -checklevel=<n> " + _("How thorough the block verification is (0-4, default: 3)") + "\n";
232 strUsage += " -txindex " + _("Maintain a full transaction index (default: 0)") + "\n";
233 strUsage += " -loadblock=<file> " + _("Imports blocks from external blk000??.dat file") + "\n";
234 strUsage += " -reindex " + _("Rebuild block chain index from current blk000??.dat files") + "\n";
235 strUsage += " -par=<n> " + _("Set the number of script verification threads (up to 16, 0 = auto, <0 = leave that many cores free, default: 0)") + "\n";
c555400c 236
c98c88b3
CF
237 strUsage += "\n"; _("Block creation options:") + "\n";
238 strUsage += " -blockminsize=<n> " + _("Set minimum block size in bytes (default: 0)") + "\n";
239 strUsage += " -blockmaxsize=<n> " + _("Set maximum block size in bytes (default: 250000)") + "\n";
240 strUsage += " -blockprioritysize=<n> " + _("Set maximum size of high-priority/low-fee transactions in bytes (default: 27000)") + "\n";
9f5b11e6 241
c98c88b3
CF
242 strUsage += "\n"; _("SSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n";
243 strUsage += " -rpcssl " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n";
244 strUsage += " -rpcsslcertificatechainfile=<file.cert> " + _("Server certificate file (default: server.cert)") + "\n";
245 strUsage += " -rpcsslprivatekeyfile=<file.pem> " + _("Server private key (default: server.pem)") + "\n";
246 strUsage += " -rpcsslciphers=<ciphers> " + _("Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)") + "\n";
9f5b11e6
WL
247
248 return strUsage;
249}
250
7a5b7535
PW
251struct CImportingNow
252{
253 CImportingNow() {
254 assert(fImporting == false);
255 fImporting = true;
256 }
257
258 ~CImportingNow() {
259 assert(fImporting == true);
260 fImporting = false;
261 }
262};
263
21eb5ada
GA
264void ThreadImport(std::vector<boost::filesystem::path> vImportFiles)
265{
7a5b7535
PW
266 RenameThread("bitcoin-loadblk");
267
7fea4846
PW
268 // -reindex
269 if (fReindex) {
270 CImportingNow imp;
271 int nFile = 0;
21eb5ada 272 while (true) {
a8a4b967 273 CDiskBlockPos pos(nFile, 0);
7fea4846
PW
274 FILE *file = OpenBlockFile(pos, true);
275 if (!file)
276 break;
277 printf("Reindexing block file blk%05u.dat...\n", (unsigned int)nFile);
278 LoadExternalBlockFile(file, &pos);
279 nFile++;
280 }
21eb5ada
GA
281 pblocktree->WriteReindexing(false);
282 fReindex = false;
283 printf("Reindexing finished\n");
284 // To avoid ending up in a situation without genesis block, re-try initializing (no-op if reindexing worked):
285 InitBlockIndex();
7a5b7535
PW
286 }
287
288 // hardcoded $DATADIR/bootstrap.dat
289 filesystem::path pathBootstrap = GetDataDir() / "bootstrap.dat";
21eb5ada 290 if (filesystem::exists(pathBootstrap)) {
7a5b7535
PW
291 FILE *file = fopen(pathBootstrap.string().c_str(), "rb");
292 if (file) {
7fea4846 293 CImportingNow imp;
7a5b7535 294 filesystem::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old";
7fea4846 295 printf("Importing bootstrap.dat...\n");
7a5b7535
PW
296 LoadExternalBlockFile(file);
297 RenameOver(pathBootstrap, pathBootstrapOld);
298 }
299 }
300
7fea4846 301 // -loadblock=
21eb5ada 302 BOOST_FOREACH(boost::filesystem::path &path, vImportFiles) {
7fea4846
PW
303 FILE *file = fopen(path.string().c_str(), "rb");
304 if (file) {
305 CImportingNow imp;
306 printf("Importing %s...\n", path.string().c_str());
307 LoadExternalBlockFile(file);
308 }
309 }
7a5b7535
PW
310}
311
9f5b11e6
WL
312/** Initialize bitcoin.
313 * @pre Parameters should be parsed and config file should be read.
314 */
c8c2fbe0 315bool AppInit2(boost::thread_group& threadGroup)
69d605f4 316{
7d80d2e3 317 // ********************************************************* Step 1: setup
69d605f4 318#ifdef _MSC_VER
814efd6f 319 // Turn off Microsoft heap dump noise
69d605f4
WL
320 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
321 _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
322#endif
323#if _MSC_VER >= 1400
814efd6f 324 // Disable confusing "helpful" text message on abort, Ctrl-C
69d605f4
WL
325 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
326#endif
3d88c9b4
PK
327#ifdef WIN32
328 // Enable Data Execution Prevention (DEP)
329 // Minimum supported OS versions: WinXP SP3, WinVista >= SP1, Win Server 2008
330 // A failure is non-critical and needs no further attention!
331#ifndef PROCESS_DEP_ENABLE
332// We define this here, because GCCs winbase.h limits this to _WIN32_WINNT >= 0x0601 (Windows 7),
333// which is not correct. Can be removed, when GCCs winbase.h is fixed!
334#define PROCESS_DEP_ENABLE 0x00000001
335#endif
336 typedef BOOL (WINAPI *PSETPROCDEPPOL)(DWORD);
337 PSETPROCDEPPOL setProcDEPPol = (PSETPROCDEPPOL)GetProcAddress(GetModuleHandleA("Kernel32.dll"), "SetProcessDEPPolicy");
338 if (setProcDEPPol != NULL) setProcDEPPol(PROCESS_DEP_ENABLE);
d23fa49c
WL
339
340 // Initialize Windows Sockets
341 WSADATA wsadata;
342 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
110257a6 343 if (ret != NO_ERROR || LOBYTE(wsadata.wVersion ) != 2 || HIBYTE(wsadata.wVersion) != 2)
d23fa49c 344 {
110257a6 345 return InitError(strprintf("Error: Winsock library failed to start (WSAStartup returned error %d)", ret));
d23fa49c 346 }
69d605f4 347#endif
6853e627 348#ifndef WIN32
3d88c9b4
PK
349 umask(077);
350
69d605f4
WL
351 // Clean shutdown on SIGTERM
352 struct sigaction sa;
353 sa.sa_handler = HandleSIGTERM;
354 sigemptyset(&sa.sa_mask);
355 sa.sa_flags = 0;
356 sigaction(SIGTERM, &sa, NULL);
357 sigaction(SIGINT, &sa, NULL);
9af080c3
MH
358
359 // Reopen debug.log on SIGHUP
360 struct sigaction sa_hup;
361 sa_hup.sa_handler = HandleSIGHUP;
362 sigemptyset(&sa_hup.sa_mask);
363 sa_hup.sa_flags = 0;
364 sigaction(SIGHUP, &sa_hup, NULL);
69d605f4
WL
365#endif
366
7d80d2e3
PW
367 // ********************************************************* Step 2: parameter interactions
368
3260b4c0 369 fTestNet = GetBoolArg("-testnet", false);
f0d8a52c 370 Checkpoints::fEnabled = GetBoolArg("-checkpoints", true);
92d5864b 371
587f929c
PW
372 if (mapArgs.count("-bind")) {
373 // when specifying an explicit binding address, you want to listen on it
374 // even when -connect or -proxy is specified
7d80d2e3 375 SoftSetBoolArg("-listen", true);
587f929c 376 }
7d80d2e3 377
f161a2c2 378 if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0) {
587f929c
PW
379 // when only connecting to trusted nodes, do not seed via DNS, or listen by default
380 SoftSetBoolArg("-dnsseed", false);
381 SoftSetBoolArg("-listen", false);
382 }
383
384 if (mapArgs.count("-proxy")) {
385 // to protect privacy, do not listen by default if a proxy server is specified
7d80d2e3 386 SoftSetBoolArg("-listen", false);
587f929c
PW
387 }
388
3bbb49de 389 if (!GetBoolArg("-listen", true)) {
587f929c 390 // do not map ports or try to retrieve public IP when not listening (pointless)
7d80d2e3
PW
391 SoftSetBoolArg("-upnp", false);
392 SoftSetBoolArg("-discover", false);
393 }
394
587f929c
PW
395 if (mapArgs.count("-externalip")) {
396 // if an explicit public IP is specified, do not try to find others
397 SoftSetBoolArg("-discover", false);
398 }
399
3260b4c0 400 if (GetBoolArg("-salvagewallet", false)) {
eed1785f
GA
401 // Rewrite just private keys: rescan to find transactions
402 SoftSetBoolArg("-rescan", true);
403 }
404
ba29a559
PW
405 // Make sure enough file descriptors are available
406 int nBind = std::max((int)mapArgs.count("-bind"), 1);
407 nMaxConnections = GetArg("-maxconnections", 125);
03f49808 408 nMaxConnections = std::max(std::min(nMaxConnections, (int)(FD_SETSIZE - nBind - MIN_CORE_FILEDESCRIPTORS)), 0);
ba29a559
PW
409 int nFD = RaiseFileDescriptorLimit(nMaxConnections + MIN_CORE_FILEDESCRIPTORS);
410 if (nFD < MIN_CORE_FILEDESCRIPTORS)
411 return InitError(_("Not enough file descriptors available."));
412 if (nFD - MIN_CORE_FILEDESCRIPTORS < nMaxConnections)
413 nMaxConnections = nFD - MIN_CORE_FILEDESCRIPTORS;
414
7d80d2e3
PW
415 // ********************************************************* Step 3: parameter-to-internal-flags
416
3260b4c0
PK
417 fDebug = GetBoolArg("-debug", false);
418 fBenchmark = GetBoolArg("-benchmark", false);
d07eaba1 419
f9cae832
PW
420 // -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency
421 nScriptCheckThreads = GetArg("-par", 0);
ebd7e8bf
DS
422 if (nScriptCheckThreads <= 0)
423 nScriptCheckThreads += boost::thread::hardware_concurrency();
69e07747 424 if (nScriptCheckThreads <= 1)
f9cae832
PW
425 nScriptCheckThreads = 0;
426 else if (nScriptCheckThreads > MAX_SCRIPTCHECK_THREADS)
427 nScriptCheckThreads = MAX_SCRIPTCHECK_THREADS;
428
d07eaba1
JG
429 // -debug implies fDebug*
430 if (fDebug)
431 fDebugNet = true;
432 else
3260b4c0 433 fDebugNet = GetBoolArg("-debugnet", false);
d07eaba1 434
69d605f4
WL
435 if (fDaemon)
436 fServer = true;
437 else
3260b4c0 438 fServer = GetBoolArg("-server", false);
69d605f4
WL
439
440 /* force fServer when running without GUI */
7f61f1ac
CF
441 if (!fHaveGUI)
442 fServer = true;
3260b4c0
PK
443 fPrintToConsole = GetBoolArg("-printtoconsole", false);
444 fPrintToDebugger = GetBoolArg("-printtodebugger", false);
445 fLogTimestamps = GetBoolArg("-logtimestamps", false);
69d605f4 446
7d80d2e3
PW
447 if (mapArgs.count("-timeout"))
448 {
449 int nNewTimeout = GetArg("-timeout", 5000);
450 if (nNewTimeout > 0 && nNewTimeout < 600000)
451 nConnectTimeout = nNewTimeout;
452 }
453
454 // Continue to put "/P2SH/" in the coinbase to monitor
455 // BIP16 support.
456 // This can be removed eventually...
457 const char* pszP2SH = "/P2SH/";
458 COINBASE_FLAGS << std::vector<unsigned char>(pszP2SH, pszP2SH+strlen(pszP2SH));
459
000dc551
GA
460 // Fee-per-kilobyte amount considered the same as "free"
461 // If you are mining, be careful setting this:
462 // if you set it to zero then
463 // a transaction spammer can cheaply fill blocks using
464 // 1-satoshi-fee transactions. It should be set above the real
465 // cost to you of processing a transaction.
466 if (mapArgs.count("-mintxfee"))
467 {
468 int64 n = 0;
469 if (ParseMoney(mapArgs["-mintxfee"], n) && n > 0)
470 CTransaction::nMinTxFee = n;
471 else
472 return InitError(strprintf(_("Invalid amount for -mintxfee=<amount>: '%s'"), mapArgs["-mintxfee"].c_str()));
473 }
474 if (mapArgs.count("-minrelaytxfee"))
475 {
476 int64 n = 0;
477 if (ParseMoney(mapArgs["-minrelaytxfee"], n) && n > 0)
478 CTransaction::nMinRelayTxFee = n;
479 else
480 return InitError(strprintf(_("Invalid amount for -minrelaytxfee=<amount>: '%s'"), mapArgs["-minrelaytxfee"].c_str()));
481 }
7d80d2e3
PW
482
483 if (mapArgs.count("-paytxfee"))
484 {
485 if (!ParseMoney(mapArgs["-paytxfee"], nTransactionFee))
486 return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s'"), mapArgs["-paytxfee"].c_str()));
487 if (nTransactionFee > 0.25 * COIN)
e6bc9c35 488 InitWarning(_("Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction."));
7d80d2e3
PW
489 }
490
491 // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log
492
22bb0490 493 std::string strDataDir = GetDataDir().string();
eed1785f 494
7d80d2e3
PW
495 // Make sure only a single Bitcoin process is using the data directory.
496 boost::filesystem::path pathLockFile = GetDataDir() / ".lock";
497 FILE* file = fopen(pathLockFile.string().c_str(), "a"); // empty lock file; created if it doesn't exist.
498 if (file) fclose(file);
499 static boost::interprocess::file_lock lock(pathLockFile.string().c_str());
500 if (!lock.try_lock())
6b3783a9 501 return InitError(strprintf(_("Cannot obtain a lock on data directory %s. Bitcoin is probably already running."), strDataDir.c_str()));
7d80d2e3 502
7f1de3fe 503 if (GetBoolArg("-shrinkdebugfile", !fDebug))
69d605f4
WL
504 ShrinkDebugFile();
505 printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
a20c0d0f 506 printf("Bitcoin version %s (%s)\n", FormatFullVersion().c_str(), CLIENT_DATE.c_str());
31b581bc 507 printf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION));
dcb14198 508 if (!fLogTimestamps)
3f964b3c 509 printf("Startup time: %s\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()).c_str());
ee12c3d6 510 printf("Default data directory %s\n", GetDefaultDataDir().string().c_str());
110257a6 511 printf("Using data directory %s\n", strDataDir.c_str());
ba29a559 512 printf("Using at most %i connections (%i file descriptors available)\n", nMaxConnections, nFD);
7d80d2e3 513 std::ostringstream strErrors;
69d605f4 514
7d80d2e3
PW
515 if (fDaemon)
516 fprintf(stdout, "Bitcoin server starting\n");
517
f9cae832
PW
518 if (nScriptCheckThreads) {
519 printf("Using %u threads for script verification\n", nScriptCheckThreads);
520 for (int i=0; i<nScriptCheckThreads-1; i++)
21eb5ada 521 threadGroup.create_thread(&ThreadScriptCheck);
f9cae832
PW
522 }
523
7d80d2e3
PW
524 int64 nStart;
525
06494cab 526 // ********************************************************* Step 5: verify wallet database integrity
eed1785f 527
e1ca89df 528 uiInterface.InitMessage(_("Verifying wallet..."));
eed1785f
GA
529
530 if (!bitdb.Open(GetDataDir()))
531 {
1859aafe
PW
532 // try moving the database env out of the way
533 boost::filesystem::path pathDatabase = GetDataDir() / "database";
534 boost::filesystem::path pathDatabaseBak = GetDataDir() / strprintf("database.%"PRI64d".bak", GetTime());
535 try {
536 boost::filesystem::rename(pathDatabase, pathDatabaseBak);
537 printf("Moved old %s to %s. Retrying.\n", pathDatabase.string().c_str(), pathDatabaseBak.string().c_str());
538 } catch(boost::filesystem::filesystem_error &error) {
539 // failure is ok (well, not really, but it's not worse than what we started with)
540 }
541
542 // try again
543 if (!bitdb.Open(GetDataDir())) {
544 // if it still fails, it probably means we can't even create the database env
545 string msg = strprintf(_("Error initializing wallet database environment %s!"), strDataDir.c_str());
546 return InitError(msg);
547 }
eed1785f
GA
548 }
549
3260b4c0 550 if (GetBoolArg("-salvagewallet", false))
eed1785f
GA
551 {
552 // Recover readable keypairs:
553 if (!CWalletDB::Recover(bitdb, "wallet.dat", true))
554 return false;
555 }
556
d0b3e77a 557 if (filesystem::exists(GetDataDir() / "wallet.dat"))
eed1785f 558 {
d0b3e77a
GA
559 CDBEnv::VerifyResult r = bitdb.Verify("wallet.dat", CWalletDB::Recover);
560 if (r == CDBEnv::RECOVER_OK)
561 {
562 string msg = strprintf(_("Warning: wallet.dat corrupt, data salvaged!"
563 " Original wallet.dat saved as wallet.{timestamp}.bak in %s; if"
564 " your balance or transactions are incorrect you should"
22bb0490 565 " restore from a backup."), strDataDir.c_str());
5350ea41 566 InitWarning(msg);
d0b3e77a
GA
567 }
568 if (r == CDBEnv::RECOVER_FAIL)
569 return InitError(_("wallet.dat corrupt, salvage failed"));
eed1785f 570 }
eed1785f
GA
571
572 // ********************************************************* Step 6: network initialization
7d80d2e3 573
501da250
EL
574 RegisterNodeSignals(GetNodeSignals());
575
587f929c 576 int nSocksVersion = GetArg("-socks", 5);
7d80d2e3
PW
577 if (nSocksVersion != 4 && nSocksVersion != 5)
578 return InitError(strprintf(_("Unknown -socks proxy version requested: %i"), nSocksVersion));
69d605f4 579
7d80d2e3
PW
580 if (mapArgs.count("-onlynet")) {
581 std::set<enum Network> nets;
582 BOOST_FOREACH(std::string snet, mapMultiArgs["-onlynet"]) {
583 enum Network net = ParseNetwork(snet);
584 if (net == NET_UNROUTABLE)
585 return InitError(strprintf(_("Unknown network specified in -onlynet: '%s'"), snet.c_str()));
586 nets.insert(net);
587 }
588 for (int n = 0; n < NET_MAX; n++) {
589 enum Network net = (enum Network)n;
590 if (!nets.count(net))
591 SetLimited(net);
592 }
593 }
9655d73f
LD
594#if defined(USE_IPV6)
595#if ! USE_IPV6
596 else
597 SetLimited(NET_IPV6);
598#endif
599#endif
7d80d2e3 600
54ce3bad
PW
601 CService addrProxy;
602 bool fProxy = false;
587f929c 603 if (mapArgs.count("-proxy")) {
54ce3bad 604 addrProxy = CService(mapArgs["-proxy"], 9050);
587f929c
PW
605 if (!addrProxy.IsValid())
606 return InitError(strprintf(_("Invalid -proxy address: '%s'"), mapArgs["-proxy"].c_str()));
607
608 if (!IsLimited(NET_IPV4))
609 SetProxy(NET_IPV4, addrProxy, nSocksVersion);
610 if (nSocksVersion > 4) {
611#ifdef USE_IPV6
612 if (!IsLimited(NET_IPV6))
613 SetProxy(NET_IPV6, addrProxy, nSocksVersion);
614#endif
615 SetNameProxy(addrProxy, nSocksVersion);
616 }
54ce3bad
PW
617 fProxy = true;
618 }
619
620 // -tor can override normal proxy, -notor disables tor entirely
621 if (!(mapArgs.count("-tor") && mapArgs["-tor"] == "0") && (fProxy || mapArgs.count("-tor"))) {
622 CService addrOnion;
623 if (!mapArgs.count("-tor"))
624 addrOnion = addrProxy;
625 else
626 addrOnion = CService(mapArgs["-tor"], 9050);
627 if (!addrOnion.IsValid())
628 return InitError(strprintf(_("Invalid -tor address: '%s'"), mapArgs["-tor"].c_str()));
629 SetProxy(NET_TOR, addrOnion, 5);
630 SetReachable(NET_TOR);
587f929c
PW
631 }
632
633 // see Step 2: parameter interactions for more information about these
634 fNoListen = !GetBoolArg("-listen", true);
635 fDiscover = GetBoolArg("-discover", true);
636 fNameLookup = GetBoolArg("-dns", true);
928d3a01 637
7d80d2e3 638 bool fBound = false;
c73323ee 639 if (!fNoListen) {
7d80d2e3
PW
640 if (mapArgs.count("-bind")) {
641 BOOST_FOREACH(std::string strBind, mapMultiArgs["-bind"]) {
642 CService addrBind;
643 if (!Lookup(strBind.c_str(), addrBind, GetListenPort(), false))
644 return InitError(strprintf(_("Cannot resolve -bind address: '%s'"), strBind.c_str()));
c73323ee 645 fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR));
7d80d2e3 646 }
c73323ee
PK
647 }
648 else {
7d80d2e3
PW
649 struct in_addr inaddr_any;
650 inaddr_any.s_addr = INADDR_ANY;
7d80d2e3 651#ifdef USE_IPV6
c73323ee 652 fBound |= Bind(CService(in6addr_any, GetListenPort()), BF_NONE);
7d80d2e3 653#endif
c73323ee 654 fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound ? BF_REPORT_ERROR : BF_NONE);
7d80d2e3
PW
655 }
656 if (!fBound)
587f929c 657 return InitError(_("Failed to listen on any port. Use -listen=0 if you want this."));
928d3a01
JG
658 }
659
c73323ee 660 if (mapArgs.count("-externalip")) {
7d80d2e3
PW
661 BOOST_FOREACH(string strAddr, mapMultiArgs["-externalip"]) {
662 CService addrLocal(strAddr, GetListenPort(), fNameLookup);
663 if (!addrLocal.IsValid())
664 return InitError(strprintf(_("Cannot resolve -externalip address: '%s'"), strAddr.c_str()));
665 AddLocal(CService(strAddr, GetListenPort(), fNameLookup), LOCAL_MANUAL);
666 }
667 }
668
587f929c
PW
669 BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"])
670 AddOneShot(strDest);
671
729b1806 672 // ********************************************************* Step 7: load block chain
7d80d2e3 673
3260b4c0 674 fReindex = GetBoolArg("-reindex", false);
7fea4846 675
f4445f99
GA
676 // Upgrading to 0.8; hard-link the old blknnnn.dat files into /blocks/
677 filesystem::path blocksDir = GetDataDir() / "blocks";
678 if (!filesystem::exists(blocksDir))
679 {
680 filesystem::create_directories(blocksDir);
681 bool linked = false;
682 for (unsigned int i = 1; i < 10000; i++) {
683 filesystem::path source = GetDataDir() / strprintf("blk%04u.dat", i);
684 if (!filesystem::exists(source)) break;
685 filesystem::path dest = blocksDir / strprintf("blk%05u.dat", i-1);
686 try {
687 filesystem::create_hard_link(source, dest);
688 printf("Hardlinked %s -> %s\n", source.string().c_str(), dest.string().c_str());
689 linked = true;
690 } catch (filesystem::filesystem_error & e) {
691 // Note: hardlink creation failing is not a disaster, it just means
692 // blocks will get re-downloaded from peers.
693 printf("Error hardlinking blk%04u.dat : %s\n", i, e.what());
694 break;
695 }
696 }
697 if (linked)
698 {
699 fReindex = true;
700 }
701 }
702
1c83b0a3
PW
703 // cache size calculations
704 size_t nTotalCache = GetArg("-dbcache", 25) << 20;
705 if (nTotalCache < (1 << 22))
706 nTotalCache = (1 << 22); // total cache cannot be less than 4 MiB
707 size_t nBlockTreeDBCache = nTotalCache / 8;
2d1fa42e 708 if (nBlockTreeDBCache > (1 << 21) && !GetBoolArg("-txindex", false))
1c83b0a3
PW
709 nBlockTreeDBCache = (1 << 21); // block tree db cache shouldn't be larger than 2 MiB
710 nTotalCache -= nBlockTreeDBCache;
711 size_t nCoinDBCache = nTotalCache / 2; // use half of the remaining cache for coindb cache
712 nTotalCache -= nCoinDBCache;
713 nCoinCacheSize = nTotalCache / 300; // coins in memory require around 300 bytes
714
f7f3a96b
PW
715 bool fLoaded = false;
716 while (!fLoaded) {
717 bool fReset = fReindex;
718 std::string strLoadError;
bb41a87d 719
f7f3a96b 720 uiInterface.InitMessage(_("Loading block index..."));
ae8bfd12 721
f7f3a96b
PW
722 nStart = GetTimeMillis();
723 do {
724 try {
725 UnloadBlockIndex();
726 delete pcoinsTip;
727 delete pcoinsdbview;
728 delete pblocktree;
729
730 pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex);
731 pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReindex);
732 pcoinsTip = new CCoinsViewCache(*pcoinsdbview);
733
734 if (fReindex)
735 pblocktree->WriteReindexing(true);
736
737 if (!LoadBlockIndex()) {
738 strLoadError = _("Error loading block database");
739 break;
740 }
741
5d274c99
PW
742 // If the loaded chain has a wrong genesis, bail out immediately
743 // (we're likely using a testnet datadir, or the other way around).
744 if (!mapBlockIndex.empty() && pindexGenesisBlock == NULL)
745 return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?"));
746
0206e38d
PK
747 // Check for changed -txindex state (only necessary if we are not reindexing anyway)
748 if (!fReindex && fTxIndex != GetBoolArg("-txindex", false)) {
749 strLoadError = _("You need to rebuild the database using -reindex to change -txindex");
750 break;
751 }
752
f7f3a96b
PW
753 // Initialize the block index (no-op if non-empty database was already loaded)
754 if (!InitBlockIndex()) {
755 strLoadError = _("Error initializing block database");
756 break;
757 }
758
e1ca89df 759 uiInterface.InitMessage(_("Verifying blocks..."));
f7f3a96b
PW
760 if (!VerifyDB()) {
761 strLoadError = _("Corrupted block database detected");
762 break;
763 }
764 } catch(std::exception &e) {
765 strLoadError = _("Error opening block database");
766 break;
767 }
1f355b66 768
f7f3a96b
PW
769 fLoaded = true;
770 } while(false);
771
772 if (!fLoaded) {
773 // first suggest a reindex
774 if (!fReset) {
775 bool fRet = uiInterface.ThreadSafeMessageBox(
0206e38d 776 strLoadError + ".\n\n" + _("Do you want to rebuild the block database now?"),
f7f3a96b
PW
777 "", CClientUIInterface::MSG_ERROR | CClientUIInterface::BTN_ABORT);
778 if (fRet) {
779 fReindex = true;
780 fRequestShutdown = false;
781 } else {
782 return false;
783 }
784 } else {
785 return InitError(strLoadError);
786 }
787 }
788 }
871c3557
B
789
790 // as LoadBlockIndex can take several minutes, it's possible the user
791 // requested to kill bitcoin-qt during the last operation. If so, exit.
792 // As the program has not fully started yet, Shutdown() is possibly overkill.
793 if (fRequestShutdown)
794 {
795 printf("Shutdown requested. Exiting.\n");
796 return false;
797 }
69d605f4
WL
798 printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart);
799
3260b4c0 800 if (GetBoolArg("-printblockindex", false) || GetBoolArg("-printblocktree", false))
1d740055 801 {
7d80d2e3
PW
802 PrintBlockTree();
803 return false;
804 }
805
806 if (mapArgs.count("-printblock"))
807 {
808 string strMatch = mapArgs["-printblock"];
809 int nFound = 0;
810 for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
1d740055 811 {
7d80d2e3
PW
812 uint256 hash = (*mi).first;
813 if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0)
814 {
815 CBlockIndex* pindex = (*mi).second;
816 CBlock block;
817 block.ReadFromDisk(pindex);
818 block.BuildMerkleTree();
819 block.print();
820 printf("\n");
821 nFound++;
822 }
1d740055 823 }
7d80d2e3
PW
824 if (nFound == 0)
825 printf("No blocks matching %s were found\n", strMatch.c_str());
826 return false;
1d740055
PW
827 }
828
eed1785f 829 // ********************************************************* Step 8: load wallet
7d80d2e3 830
ab1b288f 831 uiInterface.InitMessage(_("Loading wallet..."));
bb41a87d 832
69d605f4 833 nStart = GetTimeMillis();
dcb14198 834 bool fFirstRun = true;
e8ef3da7 835 pwalletMain = new CWallet("wallet.dat");
eed1785f 836 DBErrors nLoadWalletRet = pwalletMain->LoadWallet(fFirstRun);
7ec55267
MC
837 if (nLoadWalletRet != DB_LOAD_OK)
838 {
839 if (nLoadWalletRet == DB_CORRUPT)
6e39e7c9 840 strErrors << _("Error loading wallet.dat: Wallet corrupted") << "\n";
eed1785f
GA
841 else if (nLoadWalletRet == DB_NONCRITICAL_ERROR)
842 {
843 string msg(_("Warning: error reading wallet.dat! All keys read correctly, but transaction data"
844 " or address book entries might be missing or incorrect."));
5350ea41 845 InitWarning(msg);
eed1785f 846 }
7ec55267 847 else if (nLoadWalletRet == DB_TOO_NEW)
6e39e7c9 848 strErrors << _("Error loading wallet.dat: Wallet requires newer version of Bitcoin") << "\n";
d764d916
GA
849 else if (nLoadWalletRet == DB_NEED_REWRITE)
850 {
6e39e7c9 851 strErrors << _("Wallet needed to be rewritten: restart Bitcoin to complete") << "\n";
21e875c9 852 printf("%s", strErrors.str().c_str());
ac7c7ab9 853 return InitError(strErrors.str());
d764d916 854 }
7ec55267 855 else
6e39e7c9 856 strErrors << _("Error loading wallet.dat") << "\n";
7ec55267 857 }
439e1497
PW
858
859 if (GetBoolArg("-upgradewallet", fFirstRun))
860 {
861 int nMaxVersion = GetArg("-upgradewallet", 0);
a8c20ea9 862 if (nMaxVersion == 0) // the -upgradewallet without argument case
439e1497
PW
863 {
864 printf("Performing wallet upgrade to %i\n", FEATURE_LATEST);
865 nMaxVersion = CLIENT_VERSION;
866 pwalletMain->SetMinVersion(FEATURE_LATEST); // permanently upgrade the wallet immediately
867 }
868 else
869 printf("Allowing wallet upgrade up to %i\n", nMaxVersion);
870 if (nMaxVersion < pwalletMain->GetVersion())
871 strErrors << _("Cannot downgrade wallet") << "\n";
872 pwalletMain->SetMaxVersion(nMaxVersion);
873 }
874
875 if (fFirstRun)
876 {
877 // Create new keyUser and set as default key
878 RandAddSeedPerfmon();
879
fd61d6f5 880 CPubKey newDefaultKey;
360cfe14
PW
881 if (pwalletMain->GetKeyFromPool(newDefaultKey, false)) {
882 pwalletMain->SetDefaultKey(newDefaultKey);
883 if (!pwalletMain->SetAddressBookName(pwalletMain->vchDefaultKey.GetID(), ""))
884 strErrors << _("Cannot write default address") << "\n";
885 }
95c7db3d
PW
886
887 pwalletMain->SetBestChain(CBlockLocator(pindexBest));
439e1497
PW
888 }
889
21e875c9 890 printf("%s", strErrors.str().c_str());
69d605f4
WL
891 printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart);
892
e8ef3da7
WL
893 RegisterWallet(pwalletMain);
894
69d605f4 895 CBlockIndex *pindexRescan = pindexBest;
3260b4c0 896 if (GetBoolArg("-rescan", false))
69d605f4
WL
897 pindexRescan = pindexGenesisBlock;
898 else
899 {
e8ef3da7 900 CWalletDB walletdb("wallet.dat");
69d605f4
WL
901 CBlockLocator locator;
902 if (walletdb.ReadBestBlock(locator))
903 pindexRescan = locator.GetBlockIndex();
2aceeb01
PW
904 else
905 pindexRescan = pindexGenesisBlock;
69d605f4 906 }
89b7019b 907 if (pindexBest && pindexBest != pindexRescan)
69d605f4 908 {
ab1b288f 909 uiInterface.InitMessage(_("Rescanning..."));
69d605f4
WL
910 printf("Rescanning last %i blocks (from block %i)...\n", pindexBest->nHeight - pindexRescan->nHeight, pindexRescan->nHeight);
911 nStart = GetTimeMillis();
e8ef3da7 912 pwalletMain->ScanForWalletTransactions(pindexRescan, true);
69d605f4 913 printf(" rescan %15"PRI64d"ms\n", GetTimeMillis() - nStart);
2aceeb01
PW
914 pwalletMain->SetBestChain(CBlockLocator(pindexBest));
915 nWalletDBUpdated++;
69d605f4
WL
916 }
917
eed1785f 918 // ********************************************************* Step 9: import blocks
0fcf91ea 919
4fea06db 920 // scan for better chains in the block chain database, that are not yet connected in the active best chain
ef3988ca
PW
921 CValidationState state;
922 if (!ConnectBestBlock(state))
857c61df 923 strErrors << "Failed to connect best block";
4fea06db 924
21eb5ada 925 std::vector<boost::filesystem::path> vImportFiles;
7d80d2e3 926 if (mapArgs.count("-loadblock"))
69d605f4 927 {
7d80d2e3 928 BOOST_FOREACH(string strFile, mapMultiArgs["-loadblock"])
21eb5ada 929 vImportFiles.push_back(strFile);
52c90a2b 930 }
21eb5ada 931 threadGroup.create_thread(boost::bind(&ThreadImport, vImportFiles));
52c90a2b 932
eed1785f 933 // ********************************************************* Step 10: load peers
0fcf91ea 934
7d80d2e3 935 uiInterface.InitMessage(_("Loading addresses..."));
bb41a87d 936
7d80d2e3 937 nStart = GetTimeMillis();
7bf8b7c2 938
0fcf91ea 939 {
336fe971 940 CAddrDB::SetMessageStart(pchMessageStart);
7d80d2e3
PW
941 CAddrDB adb;
942 if (!adb.Read(addrman))
943 printf("Invalid or missing peers.dat; recreating\n");
0fcf91ea
GA
944 }
945
7d80d2e3
PW
946 printf("Loaded %i addresses from peers.dat %"PRI64d"ms\n",
947 addrman.size(), GetTimeMillis() - nStart);
69d605f4 948
eed1785f 949 // ********************************************************* Step 11: start node
69d605f4 950
69d605f4
WL
951 if (!CheckDiskSpace())
952 return false;
953
d605bc4c
GA
954 if (!strErrors.str().empty())
955 return InitError(strErrors.str());
956
69d605f4
WL
957 RandAddSeedPerfmon();
958
7d80d2e3 959 //// debug print
d210f4f5 960 printf("mapBlockIndex.size() = %"PRIszu"\n", mapBlockIndex.size());
5350ea41 961 printf("nBestHeight = %d\n", nBestHeight);
d210f4f5
PK
962 printf("setKeyPool.size() = %"PRIszu"\n", pwalletMain->setKeyPool.size());
963 printf("mapWallet.size() = %"PRIszu"\n", pwalletMain->mapWallet.size());
964 printf("mapAddressBook.size() = %"PRIszu"\n", pwalletMain->mapAddressBook.size());
7d80d2e3 965
b31499ec 966 StartNode(threadGroup);
69d605f4 967
d98bf10f
WL
968 // InitRPCMining is needed here so getwork/getblocktemplate in the GUI debug console works properly.
969 InitRPCMining();
69d605f4 970 if (fServer)
21eb5ada 971 StartRPCThreads();
69d605f4 972
a0cafb79
JG
973 // Generate coins in the background
974 GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain);
975
eed1785f 976 // ********************************************************* Step 12: finished
7d80d2e3
PW
977
978 uiInterface.InitMessage(_("Done loading"));
7d80d2e3 979
7d80d2e3
PW
980 // Add wallet transactions that aren't already in a block to mapTransactions
981 pwalletMain->ReacceptWalletTransactions();
982
b31499ec
GA
983 // Run a thread to flush wallet periodically
984 threadGroup.create_thread(boost::bind(&ThreadFlushWalletDB, boost::ref(pwalletMain->strWalletFile)));
69d605f4 985
b31499ec 986 return !fRequestShutdown;
69d605f4 987}
This page took 0.299951 seconds and 4 git commands to generate.