Anoncoin  0.9.4
P2P Digital Currency
init.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin developers
3 // Copyright (c) 2013-2015 The Anoncoin Core developers
4 // Distributed under the MIT/X11 software license, see the accompanying
5 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 
7 // Many builder specific things set in the config file, ENABLE_WALLET is a good example. Don't forget to include it this way in your source files.
8 #if defined(HAVE_CONFIG_H)
10 #endif
11 
12 #include "init.h"
13 
14 #include "addrman.h"
15 #include "checkpoints.h"
16 #include "key.h"
17 #include "main.h"
18 #include "miner.h"
19 #include "net.h"
20 #include "rpcserver.h"
21 #include "txdb.h"
22 #include "ui_interface.h"
23 #include "util.h"
24 #ifdef ENABLE_WALLET
25 #include "db.h"
26 #include "wallet.h"
27 #include "walletdb.h"
28 #endif
29 
30 #ifdef ENABLE_I2PSAM
31 #include "i2pwrapper.h"
32 #endif
33 
34 #include <stdint.h>
35 #include <stdio.h>
36 
37 #ifndef WIN32
38 #include <signal.h>
39 #endif
40 
41 #include <boost/algorithm/string/predicate.hpp>
42 #include <boost/filesystem.hpp>
43 #include <boost/interprocess/sync/file_lock.hpp>
44 #include <openssl/crypto.h>
45 
46 using namespace std;
47 using namespace boost;
48 
49 #ifdef ENABLE_WALLET
50 std::string strWalletFile;
52 #endif
53 
54 #ifdef WIN32
55 // Win32 LevelDB doesn't use filedescriptors, and the ones used for
56 // accessing block files, don't count towards to fd_set size limit
57 // anyway.
58 #define MIN_CORE_FILEDESCRIPTORS 0
59 #else
60 #define MIN_CORE_FILEDESCRIPTORS 150
61 #endif
62 
63 // Used to pass flags to the Bind() function
64 enum BindFlags {
65  BF_NONE = 0,
66  BF_EXPLICIT = (1U << 0),
67  BF_REPORT_ERROR = (1U << 1)
68 };
69 
70 
72 //
73 // Shutdown
74 //
75 
76 //
77 // Thread management and startup/shutdown:
78 //
79 // The network-processing threads are all part of a thread group
80 // created by AppInit() or the Qt main() function.
81 //
82 // A clean exit happens when StartShutdown() or the SIGTERM
83 // signal handler sets fRequestShutdown, which triggers
84 // the DetectShutdownThread(), which interrupts the main thread group.
85 // DetectShutdownThread() then exits, which causes AppInit() to
86 // continue (it .joins the shutdown thread).
87 // Shutdown() is then
88 // called to clean up database connections, and stop other
89 // threads that should only be stopped after the main network-processing
90 // threads have exited.
91 //
92 // Note that if running -daemon the parent process returns from AppInit2
93 // before adding any threads to the threadGroup, so .join_all() returns
94 // immediately and the parent exits from main().
95 //
96 // Shutdown for Qt is very similar, only it uses a QTimer to detect
97 // fRequestShutdown getting set, and then does the normal Qt
98 // shutdown thing.
99 //
100 
101 volatile bool fRequestShutdown = false;
102 
104 {
105  fRequestShutdown = true;
106 }
108 {
109  return fRequestShutdown;
110 }
111 
112 static CCoinsViewDB *pcoinsdbview;
113 
114 void Shutdown()
115 {
116  LogPrintf("Shutdown : In progress...\n");
117  static CCriticalSection cs_Shutdown;
118  TRY_LOCK(cs_Shutdown, lockShutdown);
119  if (!lockShutdown) return;
120 
121  RenameThread("anoncoin-shutoff");
123  StopRPCThreads();
125 #ifdef ENABLE_WALLET
126  if (pwalletMain)
127  bitdb.Flush(false);
128  GenerateAnoncoins(false, NULL, 0);
129 #endif
130  StopNode();
132  {
133  LOCK(cs_main);
134 #ifdef ENABLE_WALLET
135  if (pwalletMain)
136  pwalletMain->SetBestChain(chainActive.GetLocator());
137 #endif
138  if (pblocktree)
139  pblocktree->Flush();
140  if (pcoinsTip)
141  pcoinsTip->Flush();
142  delete pcoinsTip; pcoinsTip = NULL;
143  delete pcoinsdbview; pcoinsdbview = NULL;
144  delete pblocktree; pblocktree = NULL;
145  }
146 #ifdef ENABLE_WALLET
147  if (pwalletMain)
148  bitdb.Flush(true);
149 #endif
150  boost::filesystem::remove(GetPidFile());
152 #ifdef ENABLE_WALLET
153  if (pwalletMain)
154  delete pwalletMain;
155 #endif
156  LogPrintf("Shutdown : done\n");
157 }
158 
159 //
160 // Signal handlers are very limited in what they are allowed to do, so:
161 //
162 void HandleSIGTERM(int)
163 {
164  fRequestShutdown = true;
165 }
166 
167 void HandleSIGHUP(int)
168 {
169  fReopenDebugLog = true;
170 }
171 
172 bool static InitError(const std::string &str)
173 {
175  return false;
176 }
177 
178 bool static InitWarning(const std::string &str)
179 {
181  return true;
182 }
183 
184 bool static Bind(const CService &addr, unsigned int flags) {
185  if (!(flags & BF_EXPLICIT) && IsLimited(addr))
186  return false;
187  std::string strError;
188  if (!BindListenPort(addr, strError)) {
189  if (flags & BF_REPORT_ERROR)
190  return InitError(strError);
191  return false;
192  }
193  return true;
194 }
195 
196 // Core-specific options shared between UI, daemon and RPC client
197 std::string HelpMessage(HelpMessageMode hmm)
198 {
199  string strUsage = _("Options:") + "\n";
200  strUsage += " -? " + _("This help message") + "\n";
201  strUsage += " -alertnotify=<cmd> " + _("Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)") + "\n";
202  strUsage += " -blocknotify=<cmd> " + _("Execute command when the best block changes (%s in cmd is replaced by block hash)") + "\n";
203  strUsage += " -checkblocks=<n> " + _("How many blocks to check at startup (default: 288, 0 = all)") + "\n";
204  strUsage += " -checklevel=<n> " + _("How thorough the block verification of -checkblocks is (0-4, default: 3)") + "\n";
205  strUsage += " -conf=<file> " + _("Specify configuration file (default: anoncoin.conf)") + "\n";
206  if (hmm == HMM_ANONCOIND)
207  {
208 #if !defined(WIN32)
209  strUsage += " -daemon " + _("Run in the background as a daemon and accept commands") + "\n";
210 #endif
211  }
212  strUsage += " -datadir=<dir> " + _("Specify data directory") + "\n";
213  strUsage += " -dbcache=<n> " + strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache) + "\n";
214  strUsage += " -loadblock=<file> " + _("Imports blocks from external blk000??.dat file") + " " + _("on startup") + "\n";
215  strUsage += " -maxorphanblocks=<n> " + strprintf(_("Keep at most <n> unconnectable blocks in memory (default: %u)"), DEFAULT_MAX_ORPHAN_BLOCKS) + "\n";
216  strUsage += " -maxorphantx=<n> " + strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS) + "\n";
217  strUsage += " -par=<n> " + strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"), -(int)boost::thread::hardware_concurrency(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS) + "\n";
218  strUsage += " -pid=<file> " + _("Specify pid file (default: anoncoind.pid)") + "\n";
219  strUsage += " -reindex " + _("Rebuild block chain index from current blk000??.dat files") + " " + _("on startup") + "\n";
220  strUsage += " -txindex " + _("Maintain a full transaction index (default: 0)") + "\n";
221 
222  strUsage += "\n" + _("Connection options:") + "\n";
223  strUsage += " -addnode=<ip> " + _("Add a node to connect to and attempt to keep the connection open") + "\n";
224  strUsage += " -banscore=<n> " + _("Threshold for disconnecting misbehaving peers (default: 100)") + "\n";
225  strUsage += " -bantime=<n> " + _("Number of seconds to keep misbehaving peers from reconnecting (default: 86400)") + "\n";
226  strUsage += " -bind=<addr> " + _("Bind to given address and always listen on it. Use [host]:port notation for IPv6") + "\n";
227  strUsage += " -connect=<ip> " + _("Connect only to the specified node(s)") + "\n";
228  strUsage += " -discover " + _("Discover own IP address (default: 1 when listening and no -externalip)") + "\n";
229  strUsage += " -dns " + _("Allow DNS lookups for -addnode, -seednode and -connect") + " " + _("(default: 1)") + "\n";
230  strUsage += " -dnsseed " + _("Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)") + "\n";
231  strUsage += " -forcednsseed " + _("Always query for peer addresses via DNS lookup (default: 0)") + "\n";
232  strUsage += " -externalip=<ip> " + _("Specify your own public address") + "\n";
233  strUsage += " -listen " + _("Accept connections from outside (default: 1 if no -proxy or -connect)") + "\n";
234  strUsage += " -maxconnections=<n> " + _("Maintain at most <n> connections to peers (default: 125)") + "\n";
235  strUsage += " -maxreceivebuffer=<n> " + _("Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)") + "\n";
236  strUsage += " -maxsendbuffer=<n> " + _("Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)") + "\n";
237  strUsage += " -onion=<ip:port> " + _("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)") + "\n";
238  strUsage += " -onlynet=<net> " + _("Only connect to nodes in network <net> (ipv4, ipv6, onion or i2p)") + "\n";
239  strUsage += " -port=<port> " + _("Listen for connections on <port> (default: 9333 or testnet: 19333)") + "\n";
240  strUsage += " -proxy=<ip:port> " + _("Connect through SOCKS5 proxy") + "\n";
241  strUsage += " -seednode=<ip> " + _("Connect to a node to retrieve peer addresses, and disconnect") + "\n";
242  strUsage += " -timeout=<n> " + _("Specify connection timeout in milliseconds (default: 20000)") + "\n";
243 #ifdef USE_UPNP
244 #if USE_UPNP
245  strUsage += " -upnp " + _("Use UPnP to map the listening port (default: 1 when listening)") + "\n";
246 #else
247  strUsage += " -upnp " + _("Use UPnP to map the listening port (default: 0)") + "\n";
248 #endif
249 #endif
250 
251 #ifdef ENABLE_WALLET
252  strUsage += "\n" + _("Wallet options:") + "\n";
253  strUsage += " -disablewallet " + _("Do not load the wallet and disable wallet RPC calls") + "\n";
254  strUsage += " -keypool=<n> " + _("Set key pool size to <n> (default: 100)") + "\n";
255  strUsage += " -paytxfee=<amt> " + _("Fee per kB to add to transactions you send") + "\n";
256  strUsage += " -rescan " + _("Rescan the block chain for missing wallet transactions") + " " + _("on startup") + "\n";
257  strUsage += " -salvagewallet " + _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup") + "\n";
258  strUsage += " -spendzeroconfchange " + _("Spend unconfirmed change when sending transactions (default: 1)") + "\n";
259  strUsage += " -upgradewallet " + _("Upgrade wallet to latest format") + " " + _("on startup") + "\n";
260  strUsage += " -wallet=<file> " + _("Specify wallet file (within data directory)") + " " + _("(default: wallet.dat)") + "\n";
261  strUsage += " -walletnotify=<cmd> " + _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)") + "\n";
262  strUsage += " -zapwallettxes " + _("Clear list of wallet transactions (diagnostic tool; implies -rescan)") + "\n";
263 #endif
264 
265  strUsage += "\n" + _("Debugging/Testing options:") + "\n";
266  if (GetBoolArg("-help-debug", false))
267  {
268  strUsage += " -benchmark " + _("Show benchmark information (default: 0)") + "\n";
269  strUsage += " -checkpoints " + _("Only accept block chain matching built-in checkpoints (default: 1)") + "\n";
270  strUsage += " -dblogsize=<n> " + _("Flush database activity from memory pool to disk log every <n> megabytes (default: 100)") + "\n";
271  strUsage += " -disablesafemode " + _("Disable safemode, override a real safe mode event (default: 0)") + "\n";
272  strUsage += " -testsafemode " + _("Force safe mode (default: 0)") + "\n";
273  strUsage += " -dropmessagestest=<n> " + _("Randomly drop 1 of every <n> network messages") + "\n";
274  strUsage += " -fuzzmessagestest=<n> " + _("Randomly fuzz 1 of every <n> network messages") + "\n";
275  strUsage += " -flushwallet " + _("Run a thread to flush wallet periodically (default: 1)") + "\n";
276  }
277  strUsage += " -debug=<category> " + _("Output debugging information (default: 0, supplying <category> is optional)") + "\n";
278  strUsage += " " + _("If <category> is not supplied, output all debugging information.") + "\n";
279  strUsage += " " + _("<category> can be:");
280  strUsage += " addrman, alert, coindb, db, lock, rand, rpc, selectcoins, mempool, net"; // Don't translate these and qt below
281  if (hmm == HMM_ANONCOIN_QT)
282  strUsage += ", qt";
283  strUsage += ".\n";
284 #ifdef ENABLE_WALLET
285  strUsage += " -gen " + _("Generate coins (default: 0)") + "\n";
286  strUsage += " -genproclimit=<n> " + _("Set the processor limit for when generation is on (-1 = unlimited, default: -1)") + "\n";
287 #endif
288  strUsage += " -help-debug " + _("Show all debugging options (usage: --help -help-debug)") + "\n";
289  strUsage += " -logtimestamps " + _("Prepend debug output with timestamp (default: 1)") + "\n";
290  if (GetBoolArg("-help-debug", false))
291  {
292  strUsage += " -limitfreerelay=<n> " + _("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:15)") + "\n";
293  strUsage += " -maxsigcachesize=<n> " + _("Limit size of signature cache to <n> entries (default: 50000)") + "\n";
294  }
295  strUsage += " -mintxfee=<amt> " + _("Fees smaller than this are considered zero fee (for transaction creation) (default:") + " " + FormatMoney(CTransaction::nMinTxFee) + ")" + "\n";
296  strUsage += " -minrelaytxfee=<amt> " + _("Fees smaller than this are considered zero fee (for relaying) (default:") + " " + FormatMoney(CTransaction::nMinRelayTxFee) + ")" + "\n";
297  strUsage += " -printtoconsole " + _("Send trace/debug info to console instead of debug.log file") + "\n";
298  if (GetBoolArg("-help-debug", false))
299  {
300  strUsage += " -printblock=<hash> " + _("Print block on startup, if found in block index") + "\n";
301  strUsage += " -printblocktree " + _("Print block tree on startup (default: 0)") + "\n";
302  strUsage += " -printpriority " + _("Log transaction priority and fee per kB when mining blocks (default: 0)") + "\n";
303  strUsage += " -privdb " + _("Sets the DB_PRIVATE flag in the wallet db environment (default: 1)") + "\n";
304  strUsage += " -regtest " + _("Enter regression test mode, which uses a special chain in which blocks can be solved instantly.") + "\n";
305  strUsage += " " + _("This is intended for regression testing tools and app development.") + "\n";
306  strUsage += " " + _("In this mode -genproclimit controls how many blocks are generated immediately.") + "\n";
307  }
308  strUsage += " -shrinkdebugfile " + _("Shrink debug.log file on client startup (default: 1 when no -debug)") + "\n";
309  strUsage += " -testnet " + _("Use the test network") + "\n";
310 
311  strUsage += "\n" + _("Node relay options:") + "\n";
312  strUsage += " -datacarrier " + _("Relay and mine data carrier transactions (default: 1)") + "\n";
313  strUsage += "\n" + _("Block creation options:") + "\n";
314  strUsage += " -blockminsize=<n> " + _("Set minimum block size in bytes (default: 0)") + "\n";
315  strUsage += " -blockmaxsize=<n> " + strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE) + "\n";
316  strUsage += " -blockprioritysize=<n> " + strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE) + "\n";
317 
318  strUsage += "\n" + _("RPC server options:") + "\n";
319  strUsage += " -server " + _("Accept command line and JSON-RPC commands") + "\n";
320  strUsage += " -rpcuser=<user> " + _("Username for JSON-RPC connections") + "\n";
321  strUsage += " -rpcpassword=<pw> " + _("Password for JSON-RPC connections") + "\n";
322  strUsage += " -rpcport=<port> " + _("Listen for JSON-RPC connections on <port> (default: 9332 or testnet: 19332)") + "\n";
323  strUsage += " -rpcallowip=<ip> " + _("Allow JSON-RPC connections from specified IP address") + "\n";
324  strUsage += " -rpcthreads=<n> " + _("Set the number of threads to service RPC calls (default: 4)") + "\n";
325 
326  strUsage += "\n" + _("RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n";
327  strUsage += " -rpcssl " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n";
328  strUsage += " -rpcsslcertificatechainfile=<file.cert> " + _("Server certificate file (default: server.cert)") + "\n";
329  strUsage += " -rpcsslprivatekeyfile=<file.pem> " + _("Server private key (default: server.pem)") + "\n";
330  strUsage += " -rpcsslciphers=<ciphers> " + _("Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)") + "\n";
331 
332  return strUsage;
333 }
334 
336 {
338  assert(fImporting == false);
339  fImporting = true;
340  }
341 
343  assert(fImporting == true);
344  fImporting = false;
345  }
346 };
347 
348 void ThreadImport(std::vector<boost::filesystem::path> vImportFiles)
349 {
350  RenameThread("anoncoin-loadblk");
351 
352  // -reindex
353  if (fReindex) {
354  CImportingNow imp;
355  int nFile = 0;
356  while (true) {
357  CDiskBlockPos pos(nFile, 0);
358  FILE *file = OpenBlockFile(pos, true);
359  if (!file)
360  break;
361  LogPrintf("Reindexing block file blk%05u.dat...\n", (unsigned int)nFile);
362  LoadExternalBlockFile(file, &pos);
363  nFile++;
364  }
365  pblocktree->WriteReindexing(false);
366  fReindex = false;
367  LogPrintf("Reindexing finished\n");
368  // To avoid ending up in a situation without genesis block, re-try initializing (no-op if reindexing worked):
369  InitBlockIndex();
370  }
371 
372  // hardcoded $DATADIR/bootstrap.dat
373  filesystem::path pathBootstrap = GetDataDir() / "bootstrap.dat";
374  if (filesystem::exists(pathBootstrap)) {
375  FILE *file = fopen(pathBootstrap.string().c_str(), "rb");
376  if (file) {
377  CImportingNow imp;
378  filesystem::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old";
379  LogPrintf("Importing bootstrap.dat...\n");
380  LoadExternalBlockFile(file);
381  RenameOver(pathBootstrap, pathBootstrapOld);
382  } else {
383  LogPrintf("Warning: Could not open bootstrap file %s\n", pathBootstrap.string());
384  }
385  }
386 
387  // -loadblock=
388  BOOST_FOREACH(boost::filesystem::path &path, vImportFiles) {
389  FILE *file = fopen(path.string().c_str(), "rb");
390  if (file) {
391  CImportingNow imp;
392  LogPrintf("Importing blocks file %s...\n", path.string());
393  LoadExternalBlockFile(file);
394  } else {
395  LogPrintf("Warning: Could not open blocks file %s\n", path.string());
396  }
397  }
398 }
399 
404 bool InitSanityCheck(void)
405 {
406  if(!ECC_InitSanityCheck()) {
407  InitError("OpenSSL appears to lack support for elliptic curve cryptography. For more "
408  "information, visit https://en.bitcoin.it/wiki/OpenSSL_and_EC_Libraries");
409  return false;
410  }
411 
412  // TODO: remaining sanity checks, see #4081
413 
414  return true;
415 }
416 
420 bool AppInit2(boost::thread_group& threadGroup)
421 {
422  // ********************************************************* Step 1: setup
423 #ifdef _MSC_VER
424  // Turn off Microsoft heap dump noise
425  _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
426  _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
427 #endif
428 #if _MSC_VER >= 1400
429  // Disable confusing "helpful" text message on abort, Ctrl-C
430  _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
431 #endif
432 #ifdef WIN32
433  // Enable Data Execution Prevention (DEP)
434  // Minimum supported OS versions: WinXP SP3, WinVista >= SP1, Win Server 2008
435  // A failure is non-critical and needs no further attention!
436 #ifndef PROCESS_DEP_ENABLE
437  // We define this here, because GCCs winbase.h limits this to _WIN32_WINNT >= 0x0601 (Windows 7),
438  // which is not correct. Can be removed, when GCCs winbase.h is fixed!
439 #define PROCESS_DEP_ENABLE 0x00000001
440 #endif
441  typedef BOOL (WINAPI *PSETPROCDEPPOL)(DWORD);
442  PSETPROCDEPPOL setProcDEPPol = (PSETPROCDEPPOL)GetProcAddress(GetModuleHandleA("Kernel32.dll"), "SetProcessDEPPolicy");
443  if (setProcDEPPol != NULL) setProcDEPPol(PROCESS_DEP_ENABLE);
444 
445  // Initialize Windows Sockets
446  WSADATA wsadata;
447  int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
448  if (ret != NO_ERROR || LOBYTE(wsadata.wVersion ) != 2 || HIBYTE(wsadata.wVersion) != 2)
449  {
450  return InitError(strprintf("Error: Winsock library failed to start (WSAStartup returned error %d)", ret));
451  }
452 #endif
453 #ifndef WIN32
454  umask(077);
455 
456  // Clean shutdown on SIGTERM
457  struct sigaction sa;
458  sa.sa_handler = HandleSIGTERM;
459  sigemptyset(&sa.sa_mask);
460  sa.sa_flags = 0;
461  sigaction(SIGTERM, &sa, NULL);
462  sigaction(SIGINT, &sa, NULL);
463 
464  // Reopen debug.log on SIGHUP
465  struct sigaction sa_hup;
466  sa_hup.sa_handler = HandleSIGHUP;
467  sigemptyset(&sa_hup.sa_mask);
468  sa_hup.sa_flags = 0;
469  sigaction(SIGHUP, &sa_hup, NULL);
470 
471 #if defined (__SVR4) && defined (__sun)
472  // ignore SIGPIPE on Solaris
473  signal(SIGPIPE, SIG_IGN);
474 #endif
475 #endif
476 
477  // ********************************************************* Step 2: parameter interactions
478 
479  if (mapArgs.count("-bind")) {
480  // when specifying an explicit binding address, you want to listen on it
481  // even when -connect or -proxy is specified
482  if (SoftSetBoolArg("-listen", true))
483  LogPrintf("AppInit2 : parameter interaction: -bind set -> setting -listen=1\n");
484  }
485 
486  if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0) {
487  // when only connecting to trusted nodes, do not seed via DNS, or listen by default
488  if (SoftSetBoolArg("-dnsseed", false))
489  LogPrintf("AppInit2 : parameter interaction: -connect set -> setting -dnsseed=0\n");
490  if (SoftSetBoolArg("-listen", false))
491  LogPrintf("AppInit2 : parameter interaction: -connect set -> setting -listen=0\n");
492  }
493 
494  if (mapArgs.count("-proxy")) {
495  // to protect privacy, do not listen by default if a default proxy server is specified
496  if (SoftSetBoolArg("-listen", false))
497  LogPrintf("AppInit2 : parameter interaction: -proxy set -> setting -listen=0\n");
498  }
499 
500  if (!GetBoolArg("-listen", true)) {
501  // do not map ports or try to retrieve public IP when not listening (pointless)
502  if (SoftSetBoolArg("-upnp", false))
503  LogPrintf("AppInit2 : parameter interaction: -listen=0 -> setting -upnp=0\n");
504  if (SoftSetBoolArg("-discover", false))
505  LogPrintf("AppInit2 : parameter interaction: -listen=0 -> setting -discover=0\n");
506  }
507 
508  if (mapArgs.count("-externalip")) {
509  // if an explicit public IP is specified, do not try to find others
510  if (SoftSetBoolArg("-discover", false))
511  LogPrintf("AppInit2 : parameter interaction: -externalip set -> setting -discover=0\n");
512  }
513 
514  if (GetBoolArg("-salvagewallet", false)) {
515  // Rewrite just private keys: rescan to find transactions
516  if (SoftSetBoolArg("-rescan", true))
517  LogPrintf("AppInit2 : parameter interaction: -salvagewallet=1 -> setting -rescan=1\n");
518  }
519 
520  // -zapwallettx implies a rescan
521  if (GetBoolArg("-zapwallettxes", false)) {
522  if (SoftSetBoolArg("-rescan", true))
523  LogPrintf("AppInit2 : parameter interaction: -zapwallettxes=1 -> setting -rescan=1\n");
524  }
525 
526  // Make sure enough file descriptors are available
527  int nBind = std::max((int)mapArgs.count("-bind"), 1);
528  nMaxConnections = GetArg("-maxconnections", 125);
529  nMaxConnections = std::max(std::min(nMaxConnections, (int)(FD_SETSIZE - nBind - MIN_CORE_FILEDESCRIPTORS)), 0);
530  int nFD = RaiseFileDescriptorLimit(nMaxConnections + MIN_CORE_FILEDESCRIPTORS);
531  if (nFD < MIN_CORE_FILEDESCRIPTORS)
532  return InitError(_("Not enough file descriptors available."));
533  if (nFD - MIN_CORE_FILEDESCRIPTORS < nMaxConnections)
534  nMaxConnections = nFD - MIN_CORE_FILEDESCRIPTORS;
535 
536  // ********************************************************* Step 3: parameter-to-internal-flags
537 
538  fDebug = !mapMultiArgs["-debug"].empty();
539  // Special-case: if -debug=0/-nodebug is set, turn off debugging messages
540  const vector<string>& categories = mapMultiArgs["-debug"];
541  if (GetBoolArg("-nodebug", false) || find(categories.begin(), categories.end(), string("0")) != categories.end())
542  fDebug = false;
543 
544  // Check for -debugnet (deprecated)
545  if (GetBoolArg("-debugnet", false))
546  InitWarning(_("Warning: Deprecated argument -debugnet ignored, use -debug=net"));
547  // Check for -socks - as this is a privacy risk to continue, exit here
548  if (mapArgs.count("-socks"))
549  return InitError(_("Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported."));
550  // Check for -tor - as this is a privacy risk to continue, exit here
551  if (GetBoolArg("-tor", false))
552  return InitError(_("Error: Unsupported argument -tor found, use -onion."));
553 
554  fBenchmark = GetBoolArg("-benchmark", false);
555  mempool.setSanityCheck(GetBoolArg("-checkmempool", RegTest()));
556  Checkpoints::fEnabled = GetBoolArg("-checkpoints", true);
557 
558  // -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency
559  nScriptCheckThreads = GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS);
560  if (nScriptCheckThreads <= 0)
561  nScriptCheckThreads += boost::thread::hardware_concurrency();
562  if (nScriptCheckThreads <= 1)
564  else if (nScriptCheckThreads > MAX_SCRIPTCHECK_THREADS)
565  nScriptCheckThreads = MAX_SCRIPTCHECK_THREADS;
566 
567  fServer = GetBoolArg("-server", false);
568  fPrintToConsole = GetBoolArg("-printtoconsole", false);
569  fLogTimestamps = GetBoolArg("-logtimestamps", true);
570  setvbuf(stdout, NULL, _IOLBF, 0);
571 #ifdef ENABLE_WALLET
572  bool fDisableWallet = GetBoolArg("-disablewallet", false);
573 #endif
574 
575  if (mapArgs.count("-timeout"))
576  {
577  int nNewTimeout = GetArg("-timeout", 20000);
578  if (nNewTimeout > 0 && nNewTimeout < 600000)
579  nConnectTimeout = nNewTimeout;
580  }
581 
582  // Continue to put "/P2SH/" in the coinbase to monitor
583  // BIP16 support.
584  // This can be removed eventually...
585  const char* pszP2SH = "/P2SH/";
586  COINBASE_FLAGS << std::vector<unsigned char>(pszP2SH, pszP2SH+strlen(pszP2SH));
587 
588  // Fee-per-kilobyte amount considered the same as "free"
589  // If you are mining, be careful setting this:
590  // if you set it to zero then
591  // a transaction spammer can cheaply fill blocks using
592  // 1-satoshi-fee transactions. It should be set above the real
593  // cost to you of processing a transaction.
594  if (mapArgs.count("-mintxfee"))
595  {
596  int64_t n = 0;
597  if (ParseMoney(mapArgs["-mintxfee"], n) && n > 0)
599  else
600  return InitError(strprintf(_("Invalid amount for -mintxfee=<amount>: '%s'"), mapArgs["-mintxfee"]));
601  }
602  if (mapArgs.count("-minrelaytxfee"))
603  {
604  int64_t n = 0;
605  if (ParseMoney(mapArgs["-minrelaytxfee"], n) && n > 0)
607  else
608  return InitError(strprintf(_("Invalid amount for -minrelaytxfee=<amount>: '%s'"), mapArgs["-minrelaytxfee"]));
609  }
610 
611 #ifdef ENABLE_WALLET
612  if (mapArgs.count("-paytxfee"))
613  {
614  if (!ParseMoney(mapArgs["-paytxfee"], nTransactionFee))
615  return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s'"), mapArgs["-paytxfee"]));
616  if (nTransactionFee > nHighTransactionFeeWarning)
617  InitWarning(_("Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction."));
618  }
619  bSpendZeroConfChange = GetArg("-spendzeroconfchange", true);
620 
621  strWalletFile = GetArg("-wallet", "wallet.dat");
622 #endif
623  // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log
624  // Sanity check
625  if (!InitSanityCheck())
626  return InitError(_("Initialization sanity check failed. Anoncoin Core is shutting down."));
627 
628  std::string strDataDir = GetDataDir().string();
629 #ifdef ENABLE_WALLET
630  // Wallet file must be a plain filename without a directory
631  if (strWalletFile != boost::filesystem::basename(strWalletFile) + boost::filesystem::extension(strWalletFile))
632  return InitError(strprintf(_("Wallet %s resides outside data directory %s"), strWalletFile, strDataDir));
633 #endif
634  // Make sure only a single Anoncoin process is using the data directory.
635  boost::filesystem::path pathLockFile = GetDataDir() / ".lock";
636  FILE* file = fopen(pathLockFile.string().c_str(), "a"); // empty lock file; created if it doesn't exist.
637  if (file) fclose(file);
638  static boost::interprocess::file_lock lock(pathLockFile.string().c_str());
639  if (!lock.try_lock())
640  return InitError(strprintf(_("Cannot obtain a lock on data directory %s. Anoncoin Core is probably already running."), strDataDir));
641 
642  if (GetBoolArg("-shrinkdebugfile", !fDebug))
643  ShrinkDebugFile();
644  LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
645  LogPrintf("Anoncoin version %s (%s)\n", FormatFullVersion(), CLIENT_DATE);
646  LogPrintf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION));
647 #ifdef ENABLE_WALLET
648  LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0));
649 #endif
650  if (!fLogTimestamps)
651  LogPrintf("Startup time: %s\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()));
652  LogPrintf("Default data directory %s\n", GetDefaultDataDir().string());
653  LogPrintf("Using data directory %s\n", strDataDir);
654  LogPrintf("Using at most %i connections (%i file descriptors available)\n", nMaxConnections, nFD);
655  std::ostringstream strErrors;
656 
657 #ifdef ENABLE_I2PSAM
658  if( !GetBoolArg("-stfu", false) && !IsBehindDarknet() )
659  InitWarning("Anoncoin is running on clearnet!\n");
660 #endif
661 
662  if (nScriptCheckThreads) {
663  LogPrintf("Using %u threads for script verification\n", nScriptCheckThreads);
664  for (int i=0; i<nScriptCheckThreads-1; i++)
665  threadGroup.create_thread(&ThreadScriptCheck);
666  }
667 
668  int64_t nStart;
669 
670 #if defined(USE_SSE2)
671  scrypt_detect_sse2();
672 #endif
673 
674  // ********************************************************* Step 5: verify wallet database integrity
675 #ifdef ENABLE_WALLET
676  if (!fDisableWallet) {
677  LogPrintf("Using wallet %s\n", strWalletFile);
678  uiInterface.InitMessage(_("Verifying wallet..."));
679 
680  if (!bitdb.Open(GetDataDir()))
681  {
682  // try moving the database env out of the way
683  boost::filesystem::path pathDatabase = GetDataDir() / "database";
684  boost::filesystem::path pathDatabaseBak = GetDataDir() / strprintf("database.%d.bak", GetTime());
685  try {
686  boost::filesystem::rename(pathDatabase, pathDatabaseBak);
687  LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string(), pathDatabaseBak.string());
688  } catch(boost::filesystem::filesystem_error &error) {
689  // failure is ok (well, not really, but it's not worse than what we started with)
690  }
691 
692  // try again
693  if (!bitdb.Open(GetDataDir())) {
694  // if it still fails, it probably means we can't even create the database env
695  string msg = strprintf(_("Error initializing wallet database environment %s!"), strDataDir);
696  return InitError(msg);
697  }
698  }
699 
700  if (GetBoolArg("-salvagewallet", false))
701  {
702  // Recover readable keypairs:
704  return false;
705  }
706 
707  if (filesystem::exists(GetDataDir() / strWalletFile))
708  {
710  if (r == CDBEnv::RECOVER_OK)
711  {
712  string msg = strprintf(_("Warning: wallet.dat corrupt, data salvaged!"
713  " Original wallet.dat saved as wallet.{timestamp}.bak in %s; if"
714  " your balance or transactions are incorrect you should"
715  " restore from a backup."), strDataDir);
716  InitWarning(msg);
717  }
718  if (r == CDBEnv::RECOVER_FAIL)
719  return InitError(_("wallet.dat corrupt, salvage failed"));
720  }
721  } // (!fDisableWallet)
722 #endif // ENABLE_WALLET
723  // ********************************************************* Step 6: network initialization
724 
726 
727  if (mapArgs.count("-onlynet")) {
728  std::set<enum Network> nets;
729  BOOST_FOREACH(std::string snet, mapMultiArgs["-onlynet"]) {
730  enum Network net = ParseNetwork(snet);
731 
732 #ifdef ENABLE_I2PSAM
733  if (net == NET_NATIVE_I2P) {
734  // Disable upnp, force listening and no discovery on I2P only.
735 #ifdef USE_UPNP
736  SoftSetBoolArg("-upnp", false);
737 #endif
738  SoftSetBoolArg("-listen",true);
739  SoftSetBoolArg("-discover",false);
740  }
741 #endif // ENABLE_I2PSAM
742 
743  if (net == NET_UNROUTABLE)
744  return InitError(strprintf(_("Unknown network specified in -onlynet: '%s'"), snet));
745  nets.insert(net);
746  }
747  for (int n = 0; n < NET_MAX; n++) {
748  enum Network net = (enum Network)n;
749  if (!nets.count(net))
750  SetLimited(net);
751  }
752  }
753 
754  CService addrProxy;
755  bool fProxy = false;
756  if (mapArgs.count("-proxy")) {
757  addrProxy = CService(mapArgs["-proxy"], 9050);
758  if (!addrProxy.IsValid())
759  return InitError(strprintf(_("Invalid -proxy address: '%s'"), mapArgs["-proxy"]));
760 
761  if (!IsLimited(NET_IPV4))
762  SetProxy(NET_IPV4, addrProxy);
763  if (!IsLimited(NET_IPV6))
764  SetProxy(NET_IPV6, addrProxy);
765  SetNameProxy(addrProxy);
766  fProxy = true;
767  }
768 
769  // -onion can override normal proxy, -noonion disables tor entirely
770  if (!(mapArgs.count("-onion") && mapArgs["-onion"] == "0") &&
771  (fProxy || mapArgs.count("-onion"))) {
772  CService addrOnion;
773  if (!mapArgs.count("-onion"))
774  addrOnion = addrProxy;
775  else
776  addrOnion = CService(mapArgs["-onion"], 9050);
777  if (!addrOnion.IsValid())
778  return InitError(strprintf(_("Invalid -onion address: '%s'"), mapArgs["-onion"]));
779  SetProxy(NET_TOR, addrOnion);
781  }
782 
783 #ifdef ENABLE_I2PSAM
784  // At this point we really want to try and use I2P, however if the user has selected it, we may have to override the configuration
785  // file setting, and disable I2P completely, so no errors are generated or access to I2PSAM is ever attempted.
786  // Hard set override the enable flag to false.
787  if( IsLimited( NET_NATIVE_I2P ) )
788  mapArgs[ "-i2p.options.enabled" ] = "0";
789 
790  // All we need to do for -generatei2pdestination, is force I2P enabled, and set a dynamic destination, execute the normal code
791  // and near the end, after a session opened (if possible), then printout the key results, and gracefully exit the program.
792  bool fGenI2pDest = GetBoolArg("-generatei2pdestination", false);
793  if( fGenI2pDest ) { // Hard set these 2 values
794  mapArgs[ "-i2p.options.enabled" ] = "1";
795  mapArgs[ "-i2p.options.static" ] = "0";
796  }
797 
798  // Initialize some stuff here alittle early, so if GenI2pDest is run, they will be setup with
799  bool fValidI2pSession = false;
800  std:string myI2pBase32Key;
801  SAM::FullDestination myI2pKeys( GetArg("-i2p.mydestination.publickey", ""), GetArg("-i2p.mydestination.privatekey", ""), false /* isGenerated */ );
802  // If I2P is enabled, we have allot of work to do...
803  if( IsI2PEnabled() ) {
804  uiInterface.InitMessage(_("Connecting to the I2P Router..."));
805  InitializeI2pSettings(); // Make sure we have all our parameters loaded into configuration space, or set to default
806  myI2pBase32Key = GetArg("-i2p.mydestination.base32key", ""); // Localize a copy of our .b32.ip2 address too...
807  // Now we can either use a static destination address, taken from anoncoin.conf values to create a Stream Session, or
808  // generate a dynamic new one and initiate an I2P session stream that way...
809  SAM::FullDestination retI2pKeys; // Something we can compare our results too
810  if( GetBoolArg( "-i2p.options.static", false ) ) { // Running static mode, if this is true, upto the user to make sure our destination has been set
811  LogPrintf( "Attempting to create an I2P Sam session. With a static destination...\n" );
812  if( isValidI2pDestination( myI2pKeys ) ) { // Here we check to make sure the values look right
813  retI2pKeys = I2PSession::Instance().getMyDestination();
814  if( retI2pKeys.priv == myI2pKeys.priv && retI2pKeys.pub == myI2pKeys.pub && retI2pKeys.isGenerated == false )
815  fValidI2pSession = true;
816  else
817  LogPrintf( "Error - Static Destination mismatch. Result: ShutDown.\n" );
818  } else
819  LogPrintf( "Error - invalid I2P keys. Check your configuration file. Result: ShutDown\n" );
820  } else { // Generate new destination keys/address
821  LogPrintf( "Attempting to create an I2P Sam session. With a dynamic destination...\n" );
822  retI2pKeys = I2PSession::Instance().getMyDestination();
823  if( isValidI2pDestination( retI2pKeys ) ) {
824  myI2pKeys = retI2pKeys; // Ok we're going with them for this session.
825  myI2pBase32Key = I2PSession::GenerateB32AddressFromDestination( myI2pKeys.pub );
826  // At this point, we really need a hardset on the configuration parameters, as whatever was there is now wrong.
827  mapArgs[ "-i2p.mydestination.privatekey" ] = myI2pKeys.priv;
828  mapArgs[ "-i2p.mydestination.publickey" ] = myI2pKeys.pub;
829  mapArgs[ "-i2p.mydestination.base32key" ] = myI2pBase32Key;
830  fValidI2pSession = true;
831  } else
832  LogPrintf( "Error - Unable to generate a valid I2P destination. Result: ShutDown.\n" );
833  }
834  if( fValidI2pSession ) {
835  LogPrintf( "Using I2P SAM module version %s\n", FormatI2PNativeFullVersion());
836  LogPrintf( "Created a new SAM Session ID:%s, connected to Router.\n", I2PSession::Instance().getSessionID() );
837  SetReachable(NET_NATIVE_I2P); // It's now been proven the router is available.
838  } else {
839  SetLimited( NET_NATIVE_I2P ); // Don't use any i2p information
840  mapArgs[ "-i2p.options.enabled" ] = "0"; // Override the option and set it false
841  if( IsI2POnly() ) // We're wiped out, bail and exit initialization in failure
842  return InitError( "Unable to create I2P SAM session" );
843  }
844  }
845 
846  if( fGenI2pDest ) {
847  if( fValidI2pSession ) {
848  // DO NOT Put this code in, until AFTER the notification signals have been registered.
849  // noui function is used if this is anoncoind, a function in anoncoingui.cpp is called for the anoncoin-qt
850  bool bErr = uiInterface.ThreadSafeShowGeneratedI2PAddress(_("Generated an I2P destination for you."),
851  myI2pKeys.pub, myI2pKeys.priv, myI2pBase32Key,
852  GetConfigFile().string() );
853  return InitError( bErr ? _("Error - Unable to report I2P Destination.") : _("Results also written to your debug.log file"));
854  // ToDo: Not sure? Maybe this?
855  // Removed this is not an error, the signal will produce a messagebox on the gui later (if there is one)
856  // if (!bRetVal ) InitError(_("Error - Reporting I2P generated Destination keys"));
857  // if( !bRetVal ) fRequestShutdown = true;
858  // return false; // Request shutdown and terminate, this works for anoncoind, but not QT
859  // ToDo: make sure that after the generation is complete, that a request shutdown follows for both anoncoind & anoncoin-qt,
860  // **********at the moment the qt version is broke and for now, we just keep going...
861  // return InitError( "Generation of I2P Destination complete." );
862  } else
863  return InitError(_("Error - Unable to Generate I2P Destination.") );
864  } // fGenI2pDest
865 #endif // ENABLE_I2PSAM
866 
867 
868  // see Step 2: parameter interactions for more information about these
869  fNoListen = !GetBoolArg("-listen", true);
870  fDiscover = GetBoolArg("-discover", true);
871  fNameLookup = GetBoolArg("-dns", true);
872 
873  bool fBound = false;
874  if (!fNoListen) {
875  if (mapArgs.count("-bind")) {
876  BOOST_FOREACH(std::string strBind, mapMultiArgs["-bind"]) {
877  CService addrBind;
878  if (!Lookup(strBind.c_str(), addrBind, GetListenPort(), false))
879  return InitError(strprintf(_("Cannot resolve -bind address: '%s'"), strBind));
880  fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR));
881  }
882  }
883  else {
884  struct in_addr inaddr_any;
885  inaddr_any.s_addr = INADDR_ANY;
886  fBound |= Bind(CService(in6addr_any, GetListenPort()), BF_NONE);
887  fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound ? BF_REPORT_ERROR : BF_NONE);
888  }
889 
890 #ifdef ENABLE_I2PSAM
891  // Regardless of users choice on binding or not, if I2P is not limited, then we always try to bind our node to listen on the I2P socket
892  if (!IsLimited(NET_NATIVE_I2P))
893  fBound |= BindListenNativeI2P();
894 #endif
895  if (!fBound)
896  return InitError(_("Failed to listen on any port. Use -listen=0 if you want this."));
897  }
898 
899  if (mapArgs.count("-externalip")) {
900  BOOST_FOREACH(string strAddr, mapMultiArgs["-externalip"]) {
901  CService addrLocal(strAddr, GetListenPort(), fNameLookup);
902  if (!addrLocal.IsValid())
903  return InitError(strprintf(_("Cannot resolve -externalip address: '%s'"), strAddr));
905  }
906  }
907 
908  BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"])
909  AddOneShot(strDest);
910 
911  // ********************************************************* Step 7: load block chain
912 
913  fReindex = GetBoolArg("-reindex", false);
914 
915  // Upgrading to 0.8; hard-link the old blknnnn.dat files into /blocks/
916  filesystem::path blocksDir = GetDataDir() / "blocks";
917  if (!filesystem::exists(blocksDir))
918  {
919  filesystem::create_directories(blocksDir);
920  bool linked = false;
921  for (unsigned int i = 1; i < 10000; i++) {
922  filesystem::path source = GetDataDir() / strprintf("blk%04u.dat", i);
923  if (!filesystem::exists(source)) break;
924  filesystem::path dest = blocksDir / strprintf("blk%05u.dat", i-1);
925  try {
926  filesystem::create_hard_link(source, dest);
927  LogPrintf("Hardlinked %s -> %s\n", source.string(), dest.string());
928  linked = true;
929  } catch (filesystem::filesystem_error & e) {
930  // Note: hardlink creation failing is not a disaster, it just means
931  // blocks will get re-downloaded from peers.
932  LogPrintf("Error hardlinking blk%04u.dat : %s\n", i, e.what());
933  break;
934  }
935  }
936  if (linked)
937  {
938  fReindex = true;
939  }
940  }
941 
942  // cache size calculations
943  size_t nTotalCache = (GetArg("-dbcache", nDefaultDbCache) << 20);
944  if (nTotalCache < (nMinDbCache << 20))
945  nTotalCache = (nMinDbCache << 20); // total cache cannot be less than nMinDbCache
946  else if (nTotalCache > (nMaxDbCache << 20))
947  nTotalCache = (nMaxDbCache << 20); // total cache cannot be greater than nMaxDbCache
948  size_t nBlockTreeDBCache = nTotalCache / 8;
949  if (nBlockTreeDBCache > (1 << 21) && !GetBoolArg("-txindex", false))
950  nBlockTreeDBCache = (1 << 21); // block tree db cache shouldn't be larger than 2 MiB
951  nTotalCache -= nBlockTreeDBCache;
952  size_t nCoinDBCache = nTotalCache / 2; // use half of the remaining cache for coindb cache
953  nTotalCache -= nCoinDBCache;
954  nCoinCacheSize = nTotalCache / 300; // coins in memory require around 300 bytes
955 
956  bool fLoaded = false;
957  while (!fLoaded) {
958  bool fReset = fReindex;
959  std::string strLoadError;
960 
961  uiInterface.InitMessage(_("Loading block index..."));
962 
963  nStart = GetTimeMillis();
964  do {
965  try {
967  delete pcoinsTip;
968  delete pcoinsdbview;
969  delete pblocktree;
970 
971  pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex);
972  pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReindex);
973  pcoinsTip = new CCoinsViewCache(*pcoinsdbview);
974 
975  if (fReindex)
977 
978  if (!LoadBlockIndex()) {
979  strLoadError = _("Error loading block database");
980  break;
981  }
982 
983  // If the loaded chain has a wrong genesis, bail out immediately
984  // (we're likely using a testnet datadir, or the other way around).
985  if (!mapBlockIndex.empty() && chainActive.Genesis() == NULL)
986  return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?"));
987 
988  // Initialize the block index (no-op if non-empty database was already loaded)
989  if (!InitBlockIndex()) {
990  strLoadError = _("Error initializing block database");
991  break;
992  }
993 
994  // Check for changed -txindex state
995  if (fTxIndex != GetBoolArg("-txindex", false)) {
996  strLoadError = _("You need to rebuild the database using -reindex to change -txindex");
997  break;
998  }
999 
1000  uiInterface.InitMessage(_("Verifying blocks..."));
1001  if (!VerifyDB(GetArg("-checklevel", 3),
1002  GetArg("-checkblocks", 288))) {
1003  strLoadError = _("Corrupted block database detected");
1004  break;
1005  }
1006  } catch(std::exception &e) {
1007  if (fDebug) LogPrintf("%s\n", e.what());
1008  strLoadError = _("Error opening block database");
1009  break;
1010  }
1011 
1012  fLoaded = true;
1013  } while(false);
1014 
1015  if (!fLoaded) {
1016  // first suggest a reindex
1017  if (!fReset) {
1018  bool fRet = uiInterface.ThreadSafeMessageBox(
1019  strLoadError + ".\n\n" + _("Do you want to rebuild the block database now?"),
1021  if (fRet) {
1022  fReindex = true;
1023  fRequestShutdown = false;
1024  } else {
1025  LogPrintf("Aborted block database rebuild. Exiting.\n");
1026  return false;
1027  }
1028  } else {
1029  return InitError(strLoadError);
1030  }
1031  }
1032  }
1033 
1034  // As LoadBlockIndex can take several minutes, it's possible the user
1035  // requested to kill the GUI during the last operation. If so, exit.
1036  // As the program has not fully started yet, Shutdown() is possibly overkill.
1037  if (fRequestShutdown)
1038  {
1039  LogPrintf("Shutdown requested. Exiting.\n");
1040  return false;
1041  }
1042  LogPrintf(" block index %15dms\n", GetTimeMillis() - nStart);
1043 
1044  if (GetBoolArg("-printblockindex", false) || GetBoolArg("-printblocktree", false))
1045  {
1046  PrintBlockTree();
1047  return false;
1048  }
1049 
1050  if (mapArgs.count("-printblock"))
1051  {
1052  string strMatch = mapArgs["-printblock"];
1053  int nFound = 0;
1054  for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
1055  {
1056  uint256 hash = (*mi).first;
1057  if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0)
1058  {
1059  CBlockIndex* pindex = (*mi).second;
1060  CBlock block;
1061  ReadBlockFromDisk(block, pindex);
1062  block.BuildMerkleTree();
1063  block.print();
1064  LogPrintf("\n");
1065  nFound++;
1066  }
1067  }
1068  if (nFound == 0)
1069  LogPrintf("No blocks matching %s were found\n", strMatch);
1070  return false;
1071  }
1072 
1073  // ********************************************************* Step 8: load wallet
1074 #ifdef ENABLE_WALLET
1075  if (fDisableWallet) {
1076  pwalletMain = NULL;
1077  LogPrintf("Wallet disabled!\n");
1078  } else {
1079  if (GetBoolArg("-zapwallettxes", false)) {
1080  uiInterface.InitMessage(_("Zapping all transactions from wallet..."));
1081 
1082  pwalletMain = new CWallet(strWalletFile);
1083  DBErrors nZapWalletRet = pwalletMain->ZapWalletTx();
1084  if (nZapWalletRet != DB_LOAD_OK) {
1085  uiInterface.InitMessage(_("Error loading wallet.dat: Wallet corrupted"));
1086  return false;
1087  }
1088 
1089  delete pwalletMain;
1090  pwalletMain = NULL;
1091  }
1092 
1093  uiInterface.InitMessage(_("Loading wallet..."));
1094 
1095  nStart = GetTimeMillis();
1096  bool fFirstRun = true;
1097  pwalletMain = new CWallet(strWalletFile);
1098  DBErrors nLoadWalletRet = pwalletMain->LoadWallet(fFirstRun);
1099  if (nLoadWalletRet != DB_LOAD_OK)
1100  {
1101  if (nLoadWalletRet == DB_CORRUPT)
1102  strErrors << _("Error loading wallet.dat: Wallet corrupted") << "\n";
1103  else if (nLoadWalletRet == DB_NONCRITICAL_ERROR)
1104  {
1105  string msg(_("Warning: error reading wallet.dat! All keys read correctly, but transaction data"
1106  " or address book entries might be missing or incorrect."));
1107  InitWarning(msg);
1108  }
1109  else if (nLoadWalletRet == DB_TOO_NEW)
1110  strErrors << _("Error loading wallet.dat: Wallet requires newer version of Anoncoin") << "\n";
1111  else if (nLoadWalletRet == DB_NEED_REWRITE)
1112  {
1113  strErrors << _("Wallet needed to be rewritten: restart Anoncoin to complete") << "\n";
1114  LogPrintf("%s", strErrors.str());
1115  return InitError(strErrors.str());
1116  }
1117  else
1118  strErrors << _("Error loading wallet.dat") << "\n";
1119  }
1120 
1121  if (GetBoolArg("-upgradewallet", fFirstRun))
1122  {
1123  int nMaxVersion = GetArg("-upgradewallet", 0);
1124  if (nMaxVersion == 0) // the -upgradewallet without argument case
1125  {
1126  LogPrintf("Performing wallet upgrade to %i\n", FEATURE_LATEST);
1127  nMaxVersion = CLIENT_VERSION;
1128  pwalletMain->SetMinVersion(FEATURE_LATEST); // permanently upgrade the wallet immediately
1129  }
1130  else
1131  LogPrintf("Allowing wallet upgrade up to %i\n", nMaxVersion);
1132  if (nMaxVersion < pwalletMain->GetVersion())
1133  strErrors << _("Cannot downgrade wallet") << "\n";
1134  pwalletMain->SetMaxVersion(nMaxVersion);
1135  }
1136 
1137  if (fFirstRun)
1138  {
1139  // Create new keyUser and set as default key
1141 
1142  CPubKey newDefaultKey;
1143  if (pwalletMain->GetKeyFromPool(newDefaultKey)) {
1144  pwalletMain->SetDefaultKey(newDefaultKey);
1145  if (!pwalletMain->SetAddressBook(pwalletMain->vchDefaultKey.GetID(), "", "receive"))
1146  strErrors << _("Cannot write default address") << "\n";
1147  }
1148 
1149  pwalletMain->SetBestChain(chainActive.GetLocator());
1150  }
1151 
1152  LogPrintf("%s", strErrors.str());
1153  LogPrintf(" wallet %15dms\n", GetTimeMillis() - nStart);
1154 
1155  RegisterWallet(pwalletMain);
1156 
1157  CBlockIndex *pindexRescan = chainActive.Tip();
1158  if (GetBoolArg("-rescan", false))
1159  pindexRescan = chainActive.Genesis();
1160  else
1161  {
1162  CWalletDB walletdb(strWalletFile);
1163  CBlockLocator locator;
1164  if (walletdb.ReadBestBlock(locator))
1165  pindexRescan = chainActive.FindFork(locator);
1166  else
1167  pindexRescan = chainActive.Genesis();
1168  }
1169  if (chainActive.Tip() && chainActive.Tip() != pindexRescan)
1170  {
1171  uiInterface.InitMessage(_("Rescanning..."));
1172  LogPrintf("Rescanning last %i blocks (from block %i)...\n", chainActive.Height() - pindexRescan->nHeight, pindexRescan->nHeight);
1173  nStart = GetTimeMillis();
1174  pwalletMain->ScanForWalletTransactions(pindexRescan, true);
1175  LogPrintf(" rescan %15dms\n", GetTimeMillis() - nStart);
1176  pwalletMain->SetBestChain(chainActive.GetLocator());
1177  nWalletDBUpdated++;
1178  }
1179  } // (!fDisableWallet)
1180 #else // ENABLE_WALLET
1181  LogPrintf("No wallet compiled in!\n");
1182 #endif // !ENABLE_WALLET
1183  // ********************************************************* Step 9: import blocks
1184 
1185  // scan for better chains in the block chain database, that are not yet connected in the active best chain
1186  CValidationState state;
1187  if (!ActivateBestChain(state))
1188  strErrors << "Failed to connect best block";
1189 
1190  std::vector<boost::filesystem::path> vImportFiles;
1191  if (mapArgs.count("-loadblock"))
1192  {
1193  BOOST_FOREACH(string strFile, mapMultiArgs["-loadblock"])
1194  vImportFiles.push_back(strFile);
1195  }
1196  threadGroup.create_thread(boost::bind(&ThreadImport, vImportFiles));
1197 
1198 
1199  // ********************************************************* Step 10: start node
1200 
1201  if (!CheckDiskSpace())
1202  return false;
1203 
1204  if (!strErrors.str().empty())
1205  return InitError(strErrors.str());
1206 
1208 
1210  LogPrintf("mapBlockIndex.size() = %u\n", mapBlockIndex.size());
1211  LogPrintf("nBestHeight = %d\n", chainActive.Height());
1212 #ifdef ENABLE_WALLET
1213  LogPrintf("setKeyPool.size() = %u\n", pwalletMain ? pwalletMain->setKeyPool.size() : 0);
1214  LogPrintf("mapWallet.size() = %u\n", pwalletMain ? pwalletMain->mapWallet.size() : 0);
1215  LogPrintf("mapAddressBook.size() = %u\n", pwalletMain ? pwalletMain->mapAddressBook.size() : 0);
1216 #endif
1217 
1218  StartNode(threadGroup);
1219  // InitRPCMining is needed here so getwork/getblocktemplate in the GUI debug console works properly.
1220  InitRPCMining();
1221  if (fServer)
1222  StartRPCThreads();
1223 
1224 #ifdef ENABLE_WALLET
1225  // Generate coins in the background
1226  if (pwalletMain)
1227  GenerateAnoncoins(GetBoolArg("-gen", false), pwalletMain, GetArg("-genproclimit", -1));
1228 #endif
1229 
1230  // ********************************************************* Step 11: finished
1231 
1232  uiInterface.InitMessage(_("Done loading"));
1233 
1234 #ifdef ENABLE_WALLET
1235  if (pwalletMain) {
1236  // Add wallet transactions that aren't already in a block to mapTransactions
1237  pwalletMain->ReacceptWalletTransactions();
1238 
1239  // Run a thread to flush wallet periodically
1240  threadGroup.create_thread(boost::bind(&ThreadFlushWalletDB, boost::ref(pwalletMain->strWalletFile)));
1241  }
1242 #endif
1243 
1244  return !fRequestShutdown;
1245 }
const boost::filesystem::path & GetDataDir(bool fNetSpecific)
Definition: util.cpp:968
unsigned int nWalletDBUpdated
Definition: db.cpp:28
CClientUIInterface uiInterface
Definition: util.cpp:100
void SetReachable(enum Network net, bool fFlag)
Definition: net.cpp:218
CNodeSignals & GetNodeSignals()
Definition: net.cpp:97
std::set< int64_t > setKeyPool
Definition: wallet.h:138
void AddOneShot(string strDest)
Definition: net.cpp:99
bool SetAddressBook(const CTxDestination &address, const std::string &strName, const std::string &purpose)
Definition: wallet.cpp:1638
FILE * OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly)
Open a block file (blk?????.dat)
Definition: main.cpp:2729
bool AddLocal(const CService &addr, int nScore)
Definition: net.cpp:227
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
Definition: core.h:457
#define TRY_LOCK(cs, name)
Definition: sync.h:159
bool fImporting
Definition: main.cpp:47
Definition: init.h:14
std::string pub
Definition: i2psam.h:262
bool Flush()
Definition: coins.cpp:132
DBErrors ZapWalletTx()
Definition: wallet.cpp:1614
const SAM::FullDestination & getMyDestination() const
Definition: i2pwrapper.cpp:135
Definition: core.h:394
bool fDebug
Definition: util.cpp:91
HelpMessageMode
Definition: init.h:27
std::map< CTxDestination, CAddressBookData > mapAddressBook
Definition: wallet.h:174
bool ShutdownRequested()
Definition: init.cpp:107
#define strprintf
Definition: tinyformat.h:1011
BindFlags
Definition: init.cpp:64
bool SoftSetBoolArg(const std::string &strArg, bool fValue)
Set a boolean argument if it doesn't already have a value.
Definition: util.cpp:539
~CImportingNow()
Definition: init.cpp:342
bool bSpendZeroConfChange
Definition: wallet.cpp:21
static SAM::StreamSessionAdapter & Instance()
Definition: i2pwrapper.h:68
boost::filesystem::path GetPidFile()
Definition: util.cpp:1050
CPubKey vchDefaultKey
Definition: wallet.h:176
void StartShutdown()
Definition: init.cpp:103
void ShutdownRPCMining()
Definition: rpcmining.cpp:55
void ThreadScriptCheck()
Run an instance of the script checking thread.
Definition: main.cpp:1664
void setSanityCheck(bool _fSanityCheck)
Definition: txmempool.h:75
std::string strWalletFile
void SetLimited(enum Network net, bool fLimited)
Make a particular network entirely off-limits (no automatic connects to it)
Definition: net.cpp:262
CCriticalSection cs_main
Definition: main.cpp:38
int nMaxConnections
Definition: net.cpp:62
bool VerifyDB(int nCheckLevel, int nCheckDepth)
Verify consistency of the block and coin databases.
Definition: main.cpp:2812
void Flush(bool fShutdown)
Definition: db.cpp:436
bool fDiscover
Specific functions we need to implement I2P functionality.
Definition: net.cpp:52
unsigned short GetListenPort()
Definition: net.cpp:105
Don't bring GUI to foreground.
Definition: ui_interface.h:72
bool fReindex
Definition: main.cpp:48
bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest)
Definition: util.cpp:1069
bool SetMaxVersion(int nVersion)
Definition: wallet.cpp:284
std::string HelpMessage(HelpMessageMode hmm)
Definition: init.cpp:197
DBErrors
Error statuses for the wallet database.
Definition: walletdb.h:31
std::string DateTimeStrFormat(const char *pszFormat, int64_t nTime)
Definition: util.cpp:1411
void RandAddSeedPerfmon()
Definition: util.cpp:159
static int64_t nMinTxFee
Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) ...
Definition: core.h:182
string FormatMoney(int64_t n, bool fPlus)
Definition: util.cpp:308
void ReacceptWalletTransactions()
Definition: wallet.cpp:926
bool RegTest()
Definition: chainparams.h:132
void RenameThread(const char *name)
Definition: util.cpp:1368
bool isValidI2pDestination(const SAM::FullDestination &DestKeys)
Definition: i2pwrapper.cpp:294
CChain chainActive
The currently-connected chain of blocks.
Definition: main.cpp:43
bool SetDefaultKey(const CPubKey &vchPubKey)
Definition: wallet.cpp:1683
volatile bool fReopenDebugLog
Definition: util.cpp:99
void InitializeI2pSettings(void)
Definition: i2pwrapper.cpp:253
bool fBenchmark
Definition: main.cpp:49
void PrintBlockTree()
Print the loaded block tree.
Definition: main.cpp:2938
void SetBestChain(const CBlockLocator &loc)
Definition: wallet.cpp:251
int RaiseFileDescriptorLimit(int nMinFD)
Definition: util.cpp:1124
CDBEnv bitdb
Definition: db.cpp:36
uint256 BuildMerkleTree() const
Definition: core.cpp:228
CBlockLocator GetLocator(const CBlockIndex *pindex=NULL) const
Return a CBlockLocator that refers to a block in this chain (by default the tip). ...
Definition: main.cpp:395
bool SetMinVersion(enum WalletFeature, CWalletDB *pwalletdbIn=NULL, bool fExplicit=false)
Definition: wallet.cpp:257
int nScriptCheckThreads
Definition: main.cpp:46
bool SetNameProxy(CService addrProxy)
Definition: netbase.cpp:485
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or NULL if none.
Definition: main.h:1024
VerifyResult
Definition: db.h:57
int Height() const
Return the maximal height in the chain.
Definition: main.h:1055
const char * source
Definition: rpcconsole.cpp:52
CBlockTreeDB * pblocktree
Global variable that points to the active block tree (protected by cs_main)
Definition: main.cpp:437
enum Network ParseNetwork(std::string net)
Definition: netbase.cpp:52
bool fNoListen
Definition: util.cpp:97
bool GetBoolArg(const std::string &strArg, bool fDefault)
Return boolean argument or default value.
Definition: util.cpp:520
#define LogPrintf(...)
Definition: util.h:118
Access to the block database (blocks/index/)
Definition: txdb.h:47
int64_t nTransactionFee
Definition: wallet.cpp:20
volatile bool fRequestShutdown
Definition: init.cpp:101
bool IsValid() const
Definition: netbase.cpp:816
#define LOCK(cs)
Definition: sync.h:157
void UnloadBlockIndex()
Unload database information.
Definition: main.cpp:2886
bool fTxIndex
Definition: main.cpp:50
void RegisterNodeSignals(CNodeSignals &nodeSignals)
Register with a network node to receive its signals.
Definition: main.cpp:359
CImportingNow()
Definition: init.cpp:337
Definition: init.cpp:65
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netbase.h:109
An encapsulated public key.
Definition: key.h:43
bool fServer
Definition: util.cpp:95
bool ActivateBestChain(CValidationState &state)
Find the best known block, and make it the tip of the block chain.
Definition: main.cpp:2028
bool AppInit2(boost::thread_group &threadGroup)
Initialize anoncoin.
Definition: init.cpp:420
void Shutdown()
Definition: init.cpp:114
bool LoadBlockIndex()
Load the block tree and coins database from disk.
Definition: main.cpp:2894
int64_t GetTimeMillis()
Definition: util.h:304
CCoinsViewCache * pcoinsTip
Global variable that points to the active CCoinsView (protected by cs_main)
Definition: main.cpp:436
void AddTransactionsUpdated(unsigned int n)
Definition: txmempool.cpp:66
int64_t GetTime()
Definition: util.cpp:1220
int nConnectTimeout
Definition: netbase.cpp:47
void RegisterWallet(CWalletInterface *pwalletIn)
Register a wallet to receive updates from core.
Definition: main.cpp:156
void print() const
Definition: core.cpp:278
CTxMemPool mempool
Definition: main.cpp:40
std::string FormatFullVersion()
Access to the wallet database (wallet.dat)
Definition: walletdb.h:73
void ThreadImport(std::vector< boost::filesystem::path > vImportFiles)
Definition: init.cpp:348
const std::string CLIENT_DATE
void HandleSIGTERM(int)
Definition: init.cpp:162
bool fLogTimestamps
Definition: util.cpp:98
std::string strWalletFile
Definition: wallet.h:136
bool ReadBestBlock(CBlockLocator &locator)
Definition: walletdb.cpp:134
void StopRPCThreads()
Definition: rpcserver.cpp:644
Network
Definition: netbase.h:29
CBlockIndex * Genesis() const
Returns the index entry for the genesis block of this chain, or NULL if none.
Definition: main.h:1019
Capture information about block/transaction validation.
Definition: main.h:950
256-bit unsigned integer
Definition: uint256.h:532
bool BindListenPort(const CService &addrBind, string &strError)
Definition: net.cpp:1767
bool ReadBlockFromDisk(CBlock &block, const CDiskBlockPos &pos)
Definition: main.cpp:1171
bool fPrintToConsole
Definition: util.cpp:92
int ScanForWalletTransactions(CBlockIndex *pindexStart, bool fUpdate=false)
Definition: wallet.cpp:886
std::string priv
Definition: i2psam.h:263
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: main.h:698
unsigned int nCoinCacheSize
Definition: main.cpp:51
void InitRPCMining()
Definition: rpcmining.cpp:52
std::string ToString() const
Definition: uint256.h:341
CCoinsView backed by the LevelDB coin database (chainstate/)
Definition: txdb.h:30
CBlockIndex * FindFork(const CBlockLocator &locator) const
Find the last common block between this chain and a locator.
Definition: main.cpp:422
static bool Recover(CDBEnv &dbenv, std::string filename, bool fOnlyKeys)
Definition: walletdb.cpp:894
std::string _(const char *psz)
Translation function: Call Translate signal on UI interface, which returns a boost::optional result...
Definition: ui_interface.h:125
bool StopNode()
Definition: net.cpp:2044
bool Lookup(const char *pszName, std::vector< CService > &vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions)
Definition: netbase.cpp:225
bool ParseMoney(const string &str, int64_t &nRet)
Definition: util.cpp:332
static std::string GenerateB32AddressFromDestination(const std::string &destination)
Definition: i2pwrapper.cpp:203
void UnregisterAllWallets()
Unregister all wallets from core.
Definition: main.cpp:174
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances...
Definition: wallet.h:101
void GenerateAnoncoins(bool fGenerate, CWallet *pwallet, int nThreads)
Run the miner threads.
VerifyResult Verify(std::string strFile, bool(*recoverFunc)(CDBEnv &dbenv, std::string strFile))
Definition: db.cpp:144
bool InitSanityCheck(void)
Sanity checks Ensure that Anoncoin is running in a usable environment with all necessary library supp...
Definition: init.cpp:404
bool WriteReindexing(bool fReindex)
Definition: txdb.cpp:95
std::map< uint256, CWalletTx > mapWallet
Definition: wallet.h:169
boost::signals2::signal< bool(const std::string &message, const std::string &caption, unsigned int style), boost::signals2::last_value< bool > > ThreadSafeMessageBox
Show message box.
Definition: ui_interface.h:81
static int64_t nMinRelayTxFee
Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) ...
Definition: core.h:183
DBErrors LoadWallet(bool &fFirstRunRet)
Definition: wallet.cpp:1586
void HandleSIGHUP(int)
Definition: init.cpp:167
std::string GetArg(const std::string &strArg, const std::string &strDefault)
Return string argument or default value.
Definition: util.cpp:506
bool GetKeyFromPool(CPubKey &key)
Definition: wallet.cpp:1816
int nHeight
Definition: main.h:708
bool LoadExternalBlockFile(FILE *fileIn, CDiskBlockPos *dbp)
Import blocks from an external file.
Definition: main.cpp:3007
bool ECC_InitSanityCheck()
Check that required EC support is available at runtime.
Definition: key.cpp:629
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:309
bool CheckDiskSpace(uint64_t nAdditionalBytes)
Check whether enough disk space is available for an incoming block.
Definition: main.cpp:2695
#define MIN_CORE_FILEDESCRIPTORS
Definition: init.cpp:60
CKeyID GetID() const
Definition: key.h:132
bool InitBlockIndex()
Initialize a new block tree database + block data on disk.
Definition: main.cpp:2903
map< string, vector< string > > mapMultiArgs
Definition: util.cpp:90
bool Open(const boost::filesystem::path &path)
Definition: db.cpp:67
map< uint256, CBlockIndex * > mapBlockIndex
Definition: main.cpp:42
bool SetProxy(enum Network net, CService addrProxy)
Definition: netbase.cpp:467
bool fNameLookup
Definition: netbase.cpp:48
void ThreadFlushWalletDB(const std::string &strWalletFile)
void ShrinkDebugFile()
Definition: util.cpp:1187
bool IsLimited(enum Network net)
Definition: net.cpp:270
boost::signals2::signal< void(const std::string &message)> InitMessage
Progress message during initialization.
Definition: ui_interface.h:84
void StartNode(boost::thread_group &threadGroup)
Definition: net.cpp:1989
CWallet * pwalletMain
map< string, string > mapArgs
Definition: util.cpp:89
boost::filesystem::path GetDefaultDataDir()
Definition: util.cpp:936
void UnregisterNodeSignals(CNodeSignals &nodeSignals)
Unregister a network node.
Definition: main.cpp:368
void StartRPCThreads()
Definition: rpcserver.cpp:511
boost::filesystem::path GetConfigFile()
Definition: util.cpp:1007