Dash Core Source Documentation (0.16.0.1)

Find detailed information regarding the Dash Core source code.

util.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2015 The Bitcoin Core developers
3 // Copyright (c) 2014-2019 The Dash Core developers
4 // Distributed under the MIT software license, see the accompanying
5 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 
7 #include <util.h>
8 #include <fs.h>
9 
11 #include <chainparamsbase.h>
12 #include <ctpl.h>
13 #include <random.h>
14 #include <serialize.h>
15 #include <stacktraces.h>
16 #include <utilstrencodings.h>
17 
18 #include <stdarg.h>
19 
20 #if (defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__))
21 #include <pthread.h>
22 #include <pthread_np.h>
23 #endif
24 
25 #ifndef WIN32
26 // for posix_fallocate
27 #ifdef __linux__
28 
29 #ifdef _POSIX_C_SOURCE
30 #undef _POSIX_C_SOURCE
31 #endif
32 
33 #define _POSIX_C_SOURCE 200112L
34 
35 #endif // __linux__
36 
37 #include <algorithm>
38 #include <fcntl.h>
39 #include <sys/resource.h>
40 #include <sys/stat.h>
41 
42 #else
43 
44 #ifdef _MSC_VER
45 #pragma warning(disable:4786)
46 #pragma warning(disable:4804)
47 #pragma warning(disable:4805)
48 #pragma warning(disable:4717)
49 #endif
50 
51 #ifdef _WIN32_WINNT
52 #undef _WIN32_WINNT
53 #endif
54 #define _WIN32_WINNT 0x0501
55 
56 #ifdef _WIN32_IE
57 #undef _WIN32_IE
58 #endif
59 #define _WIN32_IE 0x0501
60 
61 #define WIN32_LEAN_AND_MEAN 1
62 #ifndef NOMINMAX
63 #define NOMINMAX
64 #endif
65 
66 #include <io.h> /* for _commit */
67 #include <shlobj.h>
68 #endif
69 
70 #ifdef HAVE_SYS_PRCTL_H
71 #include <sys/prctl.h>
72 #endif
73 
74 #ifdef HAVE_MALLOPT_ARENA_MAX
75 #include <malloc.h>
76 #endif
77 
78 #include <boost/algorithm/string/join.hpp>
79 #include <boost/algorithm/string/split.hpp>
80 #include <boost/algorithm/string/classification.hpp>
81 #include <boost/interprocess/sync/file_lock.hpp>
82 #include <boost/program_options/detail/config_file.hpp>
83 #include <boost/program_options/parsers.hpp>
84 #include <boost/thread.hpp>
85 #include <openssl/crypto.h>
86 #include <openssl/rand.h>
87 #include <openssl/conf.h>
88 
89 // Application startup time (used for uptime calculation)
90 const int64_t nStartupTime = GetTime();
91 
92 //Dash only features
93 bool fMasternodeMode = false;
94 bool fDisableGovernance = false;
102 int nWalletBackups = 10;
103 
104 const char * const BITCOIN_CONF_FILENAME = "dash.conf";
105 const char * const BITCOIN_PID_FILENAME = "dashd.pid";
106 const char * const DEFAULT_DEBUGLOGFILE = "debug.log";
107 
109 bool fPrintToConsole = false;
110 bool fPrintToDebugLog = true;
111 
116 std::atomic<bool> fReopenDebugLog(false);
118 
120 std::atomic<uint64_t> logCategories(0);
121 
123 static std::unique_ptr<CCriticalSection[]> ppmutexOpenSSL;
124 void locking_callback(int mode, int i, const char* file, int line) NO_THREAD_SAFETY_ANALYSIS
125 {
126  if (mode & CRYPTO_LOCK) {
128  } else {
130  }
131 }
132 
133 // Singleton for wrapping OpenSSL setup/teardown.
134 class CInit
135 {
136 public:
138  {
139  // Init OpenSSL library multithreading support
140  ppmutexOpenSSL.reset(new CCriticalSection[CRYPTO_num_locks()]);
141  CRYPTO_set_locking_callback(locking_callback);
142 
143  // OpenSSL can optionally load a config file which lists optional loadable modules and engines.
144  // We don't use them so we don't require the config. However some of our libs may call functions
145  // which attempt to load the config file, possibly resulting in an exit() or crash if it is missing
146  // or corrupt. Explicitly tell OpenSSL not to try to load the file. The result for our libs will be
147  // that the config appears to have been loaded and there are no modules/engines available.
148  OPENSSL_no_config();
149 
150 #ifdef WIN32
151  // Seed OpenSSL PRNG with current contents of the screen
152  RAND_screen();
153 #endif
154 
155  // Seed OpenSSL PRNG with performance counter
156  RandAddSeed();
157  }
159  {
160  // Securely erase the memory used by the PRNG
161  RAND_cleanup();
162  // Shutdown OpenSSL library multithreading support
163  CRYPTO_set_locking_callback(nullptr);
164  // Clear the set of locks now to maintain symmetry with the constructor.
165  ppmutexOpenSSL.reset();
166  }
167 }
169 
181 static boost::once_flag debugPrintInitFlag = BOOST_ONCE_INIT;
182 
192 static FILE* fileout = nullptr;
193 static boost::mutex* mutexDebugLog = nullptr;
194 static std::list<std::string>* vMsgsBeforeOpenLog;
195 
196 static int FileWriteStr(const std::string &str, FILE *fp)
197 {
198  return fwrite(str.data(), 1, str.size(), fp);
199 }
200 
201 static void DebugPrintInit()
202 {
203  assert(mutexDebugLog == nullptr);
204  mutexDebugLog = new boost::mutex();
205  vMsgsBeforeOpenLog = new std::list<std::string>;
206 }
207 
208 fs::path GetDebugLogPath()
209 {
210  fs::path logfile(gArgs.GetArg("-debuglogfile", DEFAULT_DEBUGLOGFILE));
211  return AbsPathForConfigVal(logfile);
212 }
213 
215 {
216  boost::call_once(&DebugPrintInit, debugPrintInitFlag);
217  boost::mutex::scoped_lock scoped_lock(*mutexDebugLog);
218 
219  assert(fileout == nullptr);
220  assert(vMsgsBeforeOpenLog);
221  fs::path pathDebug = GetDebugLogPath();
222 
223  fileout = fsbridge::fopen(pathDebug, "a");
224  if (!fileout) {
225  return false;
226  }
227 
228  setbuf(fileout, nullptr); // unbuffered
229  // dump buffered messages from before we opened the log
230  while (!vMsgsBeforeOpenLog->empty()) {
232  vMsgsBeforeOpenLog->pop_front();
233  }
234 
235  delete vMsgsBeforeOpenLog;
236  vMsgsBeforeOpenLog = nullptr;
237  return true;
238 }
239 
241 {
242  uint64_t flag;
243  std::string category;
244 };
245 
247 {
248  {BCLog::NONE, "0"},
249  {BCLog::NONE, "none"},
250  {BCLog::NET, "net"},
251  {BCLog::TOR, "tor"},
252  {BCLog::MEMPOOL, "mempool"},
253  {BCLog::HTTP, "http"},
254  {BCLog::BENCHMARK, "bench"},
255  {BCLog::ZMQ, "zmq"},
256  {BCLog::DB, "db"},
257  {BCLog::RPC, "rpc"},
258  {BCLog::ESTIMATEFEE, "estimatefee"},
259  {BCLog::ADDRMAN, "addrman"},
260  {BCLog::SELECTCOINS, "selectcoins"},
261  {BCLog::REINDEX, "reindex"},
262  {BCLog::CMPCTBLOCK, "cmpctblock"},
263  {BCLog::RANDOM, "rand"},
264  {BCLog::PRUNE, "prune"},
265  {BCLog::PROXY, "proxy"},
266  {BCLog::MEMPOOLREJ, "mempoolrej"},
267  {BCLog::LIBEVENT, "libevent"},
268  {BCLog::COINDB, "coindb"},
269  {BCLog::QT, "qt"},
270  {BCLog::LEVELDB, "leveldb"},
271  {BCLog::ALL, "1"},
272  {BCLog::ALL, "all"},
273 
274  //Start Dash
275  {BCLog::CHAINLOCKS, "chainlocks"},
276  {BCLog::GOBJECT, "gobject"},
277  {BCLog::INSTANTSEND, "instantsend"},
278  {BCLog::KEEPASS, "keepass"},
279  {BCLog::LLMQ, "llmq"},
280  {BCLog::LLMQ_DKG, "llmq-dkg"},
281  {BCLog::LLMQ_SIGS, "llmq-sigs"},
282  {BCLog::MNPAYMENTS, "mnpayments"},
283  {BCLog::MNSYNC, "mnsync"},
284  {BCLog::PRIVATESEND, "privatesend"},
285  {BCLog::SPORK, "spork"},
286  {BCLog::NETCONN, "netconn"},
287  //End Dash
288 
289 };
290 
291 bool GetLogCategory(uint64_t *f, const std::string *str)
292 {
293  if (f && str) {
294  if (*str == "") {
295  *f = BCLog::ALL;
296  return true;
297  }
298  if (*str == "dash") {
299  *f = BCLog::CHAINLOCKS
303  | BCLog::LLMQ
307  | BCLog::MNSYNC
309  | BCLog::SPORK;
310  return true;
311  }
312  for (unsigned int i = 0; i < ARRAYLEN(LogCategories); i++) {
313  if (LogCategories[i].category == *str) {
314  *f = LogCategories[i].flag;
315  return true;
316  }
317  }
318  }
319  return false;
320 }
321 
322 std::string ListLogCategories()
323 {
324  std::string ret;
325  int outcount = 0;
326  for (unsigned int i = 0; i < ARRAYLEN(LogCategories); i++) {
327  // Omit the special cases.
328  if (LogCategories[i].flag != BCLog::NONE && LogCategories[i].flag != BCLog::ALL) {
329  if (outcount != 0) ret += ", ";
330  ret += LogCategories[i].category;
331  outcount++;
332  }
333  }
334  return ret;
335 }
336 
337 std::vector<CLogCategoryActive> ListActiveLogCategories()
338 {
339  std::vector<CLogCategoryActive> ret;
340  for (unsigned int i = 0; i < ARRAYLEN(LogCategories); i++) {
341  // Omit the special cases.
342  if (LogCategories[i].flag != BCLog::NONE && LogCategories[i].flag != BCLog::ALL) {
343  CLogCategoryActive catActive;
344  catActive.category = LogCategories[i].category;
345  catActive.active = LogAcceptCategory(LogCategories[i].flag);
346  ret.push_back(catActive);
347  }
348  }
349  return ret;
350 }
351 
353 {
354  if (logCategories == BCLog::NONE)
355  return "0";
356  if (logCategories == BCLog::ALL)
357  return "1";
358 
359  std::string ret;
360  int outcount = 0;
361  for (unsigned int i = 0; i < ARRAYLEN(LogCategories); i++) {
362  // Omit the special cases.
363  if (LogCategories[i].flag != BCLog::NONE && LogCategories[i].flag != BCLog::ALL && LogAcceptCategory(LogCategories[i].flag)) {
364  if (outcount != 0) ret += ", ";
365  ret += LogCategories[i].category;
366  outcount++;
367  }
368  }
369  return ret;
370 }
371 
377 static std::string LogTimestampStr(const std::string &str, std::atomic_bool *fStartedNewLine)
378 {
379  std::string strStamped;
380 
381  if (!fLogTimestamps)
382  return str;
383 
384  if (*fStartedNewLine) {
385  int64_t nTimeMicros = GetTimeMicros();
386  strStamped = DateTimeStrFormat("%Y-%m-%d %H:%M:%S", nTimeMicros/1000000);
387  if (fLogTimeMicros)
388  strStamped += strprintf(".%06d", nTimeMicros%1000000);
389  int64_t mocktime = GetMockTime();
390  if (mocktime) {
391  strStamped += " (mocktime: " + DateTimeStrFormat("%Y-%m-%d %H:%M:%S", mocktime) + ")";
392  }
393  strStamped += ' ' + str;
394  } else
395  strStamped = str;
396 
397  return strStamped;
398 }
399 
405 static std::string LogThreadNameStr(const std::string &str, std::atomic_bool *fStartedNewLine)
406 {
407  std::string strThreadLogged;
408 
409  if (!fLogThreadNames)
410  return str;
411 
412  std::string strThreadName = GetThreadName();
413 
414  if (*fStartedNewLine)
415  strThreadLogged = strprintf("%16s | %s", strThreadName.c_str(), str.c_str());
416  else
417  strThreadLogged = str;
418 
419  return strThreadLogged;
420 }
421 
422 int LogPrintStr(const std::string &str)
423 {
424  int ret = 0; // Returns total number of characters written
425  static std::atomic_bool fStartedNewLine(true);
426 
427  std::string strThreadLogged = LogThreadNameStr(str, &fStartedNewLine);
428  std::string strTimestamped = LogTimestampStr(strThreadLogged, &fStartedNewLine);
429 
430  if (!str.empty() && str[str.size()-1] == '\n')
431  fStartedNewLine = true;
432  else
433  fStartedNewLine = false;
434 
435  if (fPrintToConsole)
436  {
437  // print to console
438  ret = fwrite(strTimestamped.data(), 1, strTimestamped.size(), stdout);
439  fflush(stdout);
440  }
441  else if (fPrintToDebugLog)
442  {
443  boost::call_once(&DebugPrintInit, debugPrintInitFlag);
444  boost::mutex::scoped_lock scoped_lock(*mutexDebugLog);
445 
446  // buffer if we haven't opened the log yet
447  if (fileout == nullptr) {
448  assert(vMsgsBeforeOpenLog);
449  ret = strTimestamped.length();
450  vMsgsBeforeOpenLog->push_back(strTimestamped);
451  }
452  else
453  {
454  // reopen the log file, if requested
455  if (fReopenDebugLog) {
456  fReopenDebugLog = false;
457  fs::path pathDebug = GetDebugLogPath();
458  if (fsbridge::freopen(pathDebug,"a",fileout) != nullptr)
459  setbuf(fileout, nullptr); // unbuffered
460  }
461 
462  ret = FileWriteStr(strTimestamped, fileout);
463  }
464  }
465  return ret;
466 }
467 
473 static std::map<std::string, std::unique_ptr<boost::interprocess::file_lock>> dir_locks;
475 static std::mutex cs_dir_locks;
476 
477 bool LockDirectory(const fs::path& directory, const std::string lockfile_name, bool probe_only)
478 {
479  std::lock_guard<std::mutex> ulock(cs_dir_locks);
480  fs::path pathLockFile = directory / lockfile_name;
481 
482  // If a lock for this directory already exists in the map, don't try to re-lock it
483  if (dir_locks.count(pathLockFile.string())) {
484  return true;
485  }
486 
487  // Create empty lock file if it doesn't exist.
488  FILE* file = fsbridge::fopen(pathLockFile, "a");
489  if (file) fclose(file);
490 
491  try {
492  auto lock = MakeUnique<boost::interprocess::file_lock>(pathLockFile.string().c_str());
493  if (!lock->try_lock()) {
494  return false;
495  }
496  if (!probe_only) {
497  // Lock successful and we're not just probing, put it into the map
498  dir_locks.emplace(pathLockFile.string(), std::move(lock));
499  }
500  } catch (const boost::interprocess::interprocess_exception& e) {
501  return error("Error while attempting to lock directory %s: %s", directory.string(), e.what());
502  }
503  return true;
504 }
505 
507 {
508  std::lock_guard<std::mutex> ulock(cs_dir_locks);
509  dir_locks.clear();
510 }
511 
529 static bool InterpretBool(const std::string& strValue)
530 {
531  if (strValue.empty())
532  return true;
533  return (atoi(strValue) != 0);
534 }
535 
538 public:
539  typedef std::map<std::string, std::vector<std::string>> MapArgs;
540 
543  static inline bool UseDefaultSection(const ArgsManager& am, const std::string& arg)
544  {
545  return (am.m_network == CBaseChainParams::MAIN || am.m_network_only_args.count(arg) == 0);
546  }
547 
549  static inline std::string NetworkArg(const ArgsManager& am, const std::string& arg)
550  {
551  assert(arg.length() > 1 && arg[0] == '-');
552  return "-" + am.m_network + "." + arg.substr(1);
553  }
554 
556  static inline void AddArgs(std::vector<std::string>& res, const MapArgs& map_args, const std::string& arg)
557  {
558  auto it = map_args.find(arg);
559  if (it != map_args.end()) {
560  res.insert(res.end(), it->second.begin(), it->second.end());
561  }
562  }
563 
567  static inline std::pair<bool,std::string> GetArgHelper(const MapArgs& map_args, const std::string& arg, bool getLast = false)
568  {
569  auto it = map_args.find(arg);
570 
571  if (it == map_args.end() || it->second.empty()) {
572  return std::make_pair(false, std::string());
573  }
574 
575  if (getLast) {
576  return std::make_pair(true, it->second.back());
577  } else {
578  return std::make_pair(true, it->second.front());
579  }
580  }
581 
582  /* Get the string value of an argument, returning a pair of a boolean
583  * indicating the argument was found, and the value for the argument
584  * if it was found (or the empty string if not found).
585  */
586  static inline std::pair<bool,std::string> GetArg(const ArgsManager &am, const std::string& arg)
587  {
588  LOCK(am.cs_args);
589  std::pair<bool,std::string> found_result(false, std::string());
590 
591  // We pass "true" to GetArgHelper in order to return the last
592  // argument value seen from the command line (so "dashd -foo=bar
593  // -foo=baz" gives GetArg(am,"foo")=={true,"baz"}
594  found_result = GetArgHelper(am.m_override_args, arg, true);
595  if (found_result.first) {
596  return found_result;
597  }
598 
599  // But in contrast we return the first argument seen in a config file,
600  // so "foo=bar \n foo=baz" in the config file gives
601  // GetArg(am,"foo")={true,"bar"}
602  if (!am.m_network.empty()) {
603  found_result = GetArgHelper(am.m_config_args, NetworkArg(am, arg));
604  if (found_result.first) {
605  return found_result;
606  }
607  }
608 
609  if (UseDefaultSection(am, arg)) {
610  found_result = GetArgHelper(am.m_config_args, arg);
611  if (found_result.first) {
612  return found_result;
613  }
614  }
615 
616  return found_result;
617  }
618 
619  /* Special test for -testnet and -regtest args, because we
620  * don't want to be confused by craziness like "[regtest] testnet=1"
621  */
622  static inline bool GetNetBoolArg(const ArgsManager &am, const std::string& net_arg, bool interpret_bool)
623  {
624  std::pair<bool,std::string> found_result(false,std::string());
625  found_result = GetArgHelper(am.m_override_args, net_arg, true);
626  if (!found_result.first) {
627  found_result = GetArgHelper(am.m_config_args, net_arg, true);
628  if (!found_result.first) {
629  return false; // not set
630  }
631  }
632  return !interpret_bool || InterpretBool(found_result.second); // is set, so evaluate
633  }
634 };
635 
657 static bool InterpretNegatedOption(std::string& key, std::string& val)
658 {
659  assert(key[0] == '-');
660 
661  size_t option_index = key.find('.');
662  if (option_index == std::string::npos) {
663  option_index = 1;
664  } else {
665  ++option_index;
666  }
667  if (key.substr(option_index, 2) == "no") {
668  bool bool_val = InterpretBool(val);
669  key.erase(option_index, 2);
670  if (!bool_val ) {
671  // Double negatives like -nofoo=0 are supported (but discouraged)
672  LogPrintf("Warning: parsed potentially confusing double-negative %s=%s\n", key, val);
673  val = "1";
674  } else {
675  return true;
676  }
677  }
678  return false;
679 }
680 
682  /* These options would cause cross-contamination if values for
683  * mainnet were used while running on regtest/testnet (or vice-versa).
684  * Setting them as section_only_args ensures that sharing a config file
685  * between mainnet and regtest/testnet won't cause problems due to these
686  * parameters by accident. */
687  m_network_only_args{
688  "-addnode", "-connect",
689  "-port", "-bind",
690  "-rpcport", "-rpcbind",
691  "-wallet",
692  }
693 {
694  // nothing to do
695 }
696 
698 {
699  // if there's no section selected, don't worry
700  if (m_network.empty()) return;
701 
702  // if it's okay to use the default section for this network, don't worry
703  if (m_network == CBaseChainParams::MAIN) return;
704 
705  for (const auto& arg : m_network_only_args) {
706  std::pair<bool, std::string> found_result;
707 
708  // if this option is overridden it's fine
710  if (found_result.first) continue;
711 
712  // if there's a network-specific value for this option, it's fine
714  if (found_result.first) continue;
715 
716  // if there isn't a default value for this option, it's fine
717  found_result = ArgsManagerHelper::GetArgHelper(m_config_args, arg);
718  if (!found_result.first) continue;
719 
720  // otherwise, issue a warning
721  LogPrintf("Warning: Config setting for %s only applied on %s network when in [%s] section.\n", arg, m_network, m_network);
722  }
723 }
724 
725 void ArgsManager::SelectConfigNetwork(const std::string& network)
726 {
727  m_network = network;
728 }
729 
730 void ArgsManager::ParseParameters(int argc, const char* const argv[])
731 {
732  LOCK(cs_args);
733  m_override_args.clear();
734 
735  for (int i = 1; i < argc; i++) {
736  std::string key(argv[i]);
737  std::string val;
738  size_t is_index = key.find('=');
739  if (is_index != std::string::npos) {
740  val = key.substr(is_index + 1);
741  key.erase(is_index);
742  }
743 #ifdef WIN32
744  std::transform(key.begin(), key.end(), key.begin(), ::tolower);
745  if (key[0] == '/')
746  key[0] = '-';
747 #endif
748 
749  if (key[0] != '-')
750  break;
751 
752  // Transform --foo to -foo
753  if (key.length() > 1 && key[1] == '-')
754  key.erase(0, 1);
755 
756  // Check for -nofoo
757  if (InterpretNegatedOption(key, val)) {
758  m_override_args[key].clear();
759  } else {
760  m_override_args[key].push_back(val);
761  }
762  }
763 }
764 
765 std::vector<std::string> ArgsManager::GetArgs(const std::string& strArg) const
766 {
767  std::vector<std::string> result = {};
768  if (IsArgNegated(strArg)) return result; // special case
769 
770  LOCK(cs_args);
771 
773  if (!m_network.empty()) {
775  }
776 
777  if (ArgsManagerHelper::UseDefaultSection(*this, strArg)) {
778  ArgsManagerHelper::AddArgs(result, m_config_args, strArg);
779  }
780 
781  return result;
782 }
783 
784 bool ArgsManager::IsArgSet(const std::string& strArg) const
785 {
786  if (IsArgNegated(strArg)) return true; // special case
787  return ArgsManagerHelper::GetArg(*this, strArg).first;
788 }
789 
790 bool ArgsManager::IsArgNegated(const std::string& strArg) const
791 {
792  LOCK(cs_args);
793 
794  const auto& ov = m_override_args.find(strArg);
795  if (ov != m_override_args.end()) return ov->second.empty();
796 
797  if (!m_network.empty()) {
798  const auto& cfs = m_config_args.find(ArgsManagerHelper::NetworkArg(*this, strArg));
799  if (cfs != m_config_args.end()) return cfs->second.empty();
800  }
801 
802  const auto& cf = m_config_args.find(strArg);
803  if (cf != m_config_args.end()) return cf->second.empty();
804 
805  return false;
806 }
807 
808 std::string ArgsManager::GetArg(const std::string& strArg, const std::string& strDefault) const
809 {
810  if (IsArgNegated(strArg)) return "0";
811  std::pair<bool,std::string> found_res = ArgsManagerHelper::GetArg(*this, strArg);
812  if (found_res.first) return found_res.second;
813  return strDefault;
814 }
815 
816 int64_t ArgsManager::GetArg(const std::string& strArg, int64_t nDefault) const
817 {
818  if (IsArgNegated(strArg)) return 0;
819  std::pair<bool,std::string> found_res = ArgsManagerHelper::GetArg(*this, strArg);
820  if (found_res.first) return atoi64(found_res.second);
821  return nDefault;
822 }
823 
824 bool ArgsManager::GetBoolArg(const std::string& strArg, bool fDefault) const
825 {
826  if (IsArgNegated(strArg)) return false;
827  std::pair<bool,std::string> found_res = ArgsManagerHelper::GetArg(*this, strArg);
828  if (found_res.first) return InterpretBool(found_res.second);
829  return fDefault;
830 }
831 
832 bool ArgsManager::SoftSetArg(const std::string& strArg, const std::string& strValue)
833 {
834  LOCK(cs_args);
835  if (IsArgSet(strArg)) return false;
836  ForceSetArg(strArg, strValue);
837  return true;
838 }
839 
840 bool ArgsManager::SoftSetBoolArg(const std::string& strArg, bool fValue)
841 {
842  if (fValue)
843  return SoftSetArg(strArg, std::string("1"));
844  else
845  return SoftSetArg(strArg, std::string("0"));
846 }
847 
848 void ArgsManager::ForceSetArg(const std::string& strArg, const std::string& strValue)
849 {
850  LOCK(cs_args);
851  m_override_args[strArg] = {strValue};
852 }
853 
854 void ArgsManager::ForceRemoveArg(const std::string& strArg)
855 {
856  LOCK(cs_args);
857 
858  const auto& ov = m_override_args.find(strArg);
859  if (ov != m_override_args.end()) {
860  m_override_args.erase(ov);
861  }
862 
863  if (!m_network.empty()) {
864  const auto& cfs = m_config_args.find(ArgsManagerHelper::NetworkArg(*this, strArg));
865  if (cfs != m_config_args.end()) {
866  m_config_args.erase(cfs);
867  }
868  }
869 
870  const auto& cf = m_config_args.find(strArg);
871  if (cf != m_config_args.end()) {
872  m_config_args.erase(cf);
873  }
874 }
875 
876 static const int screenWidth = 79;
877 static const int optIndent = 2;
878 static const int msgIndent = 7;
879 
880 std::string HelpMessageGroup(const std::string &message) {
881  return std::string(message) + std::string("\n\n");
882 }
883 
884 std::string HelpMessageOpt(const std::string &option, const std::string &message) {
885  return std::string(optIndent,' ') + std::string(option) +
886  std::string("\n") + std::string(msgIndent,' ') +
888  std::string("\n\n");
889 }
890 
891 void PrintExceptionContinue(const std::exception_ptr pex, const char* pszExceptionOrigin)
892 {
893  std::string message = strprintf("\"%s\" raised an exception\n%s", pszExceptionOrigin, GetPrettyExceptionStr(pex));
894  LogPrintf("\n\n************************\n%s\n", message);
895  fprintf(stderr, "\n\n************************\n%s\n", message.c_str());
896 }
897 
899 {
900  // Windows < Vista: C:\Documents and Settings\Username\Application Data\DashCore
901  // Windows >= Vista: C:\Users\Username\AppData\Roaming\DashCore
902  // Mac: ~/Library/Application Support/DashCore
903  // Unix: ~/.dashcore
904 #ifdef WIN32
905  // Windows
906  return GetSpecialFolderPath(CSIDL_APPDATA) / "DashCore";
907 #else
908  fs::path pathRet;
909  char* pszHome = getenv("HOME");
910  if (pszHome == nullptr || strlen(pszHome) == 0)
911  pathRet = fs::path("/");
912  else
913  pathRet = fs::path(pszHome);
914 #ifdef MAC_OSX
915  // Mac
916  return pathRet / "Library/Application Support/DashCore";
917 #else
918  // Unix
919  return pathRet / ".dashcore";
920 #endif
921 #endif
922 }
923 
924 static fs::path pathCached;
925 static fs::path pathCachedNetSpecific;
927 
928 const fs::path &GetDataDir(bool fNetSpecific)
929 {
930 
932 
933  fs::path &path = fNetSpecific ? pathCachedNetSpecific : pathCached;
934 
935  // This can be called during exceptions by LogPrintf(), so we cache the
936  // value so we don't have to do memory allocations after that.
937  if (!path.empty())
938  return path;
939 
940  if (gArgs.IsArgSet("-datadir")) {
941  path = fs::system_complete(gArgs.GetArg("-datadir", ""));
942  if (!fs::is_directory(path)) {
943  path = "";
944  return path;
945  }
946  } else {
947  path = GetDefaultDataDir();
948  }
949  if (fNetSpecific)
950  path /= BaseParams().DataDir();
951 
952  if (fs::create_directories(path)) {
953  // This is the first run, create wallets subdirectory too
954  fs::create_directories(path / "wallets");
955  }
956 
957  return path;
958 }
959 
960 fs::path GetBackupsDir()
961 {
962  if (!gArgs.IsArgSet("-walletbackupsdir"))
963  return GetDataDir() / "backups";
964 
965  return fs::absolute(gArgs.GetArg("-walletbackupsdir", ""));
966 }
967 
969 {
971 
972  pathCached = fs::path();
973  pathCachedNetSpecific = fs::path();
974 }
975 
976 fs::path GetConfigFile(const std::string& confPath)
977 {
978  return AbsPathForConfigVal(fs::path(confPath), false);
979 }
980 
981 void ArgsManager::ReadConfigStream(std::istream& stream)
982 {
983  LOCK(cs_args);
984 
985  std::set<std::string> setOptions;
986  setOptions.insert("*");
987 
988  for (boost::program_options::detail::config_file_iterator it(stream, setOptions), end; it != end; ++it)
989  {
990  std::string strKey = std::string("-") + it->string_key;
991  std::string strValue = it->value[0];
992  if (InterpretNegatedOption(strKey, strValue)) {
993  m_config_args[strKey].clear();
994  } else {
995  m_config_args[strKey].push_back(strValue);
996  }
997  }
998 }
999 
1000 void ArgsManager::ReadConfigFile(const std::string& confPath)
1001 {
1002  {
1003  LOCK(cs_args);
1004  m_config_args.clear();
1005  }
1006 
1007  fs::ifstream stream(GetConfigFile(confPath));
1008 
1009  if (stream.good()) {
1010  ReadConfigStream(stream);
1011  } else {
1012  // Create an empty dash.conf if it does not excist
1013  FILE* configFile = fopen(GetConfigFile(confPath).string().c_str(), "a");
1014  if (configFile != nullptr)
1015  fclose(configFile);
1016  return; // Nothing to read, so just return
1017  }
1018 
1019  // If datadir is changed in .conf file:
1021  if (!fs::is_directory(GetDataDir(false))) {
1022  throw std::runtime_error(strprintf("specified data directory \"%s\" does not exist.", gArgs.GetArg("-datadir", "").c_str()));
1023  }
1024 }
1025 
1026 std::string ArgsManager::GetChainName() const
1027 {
1028  bool fRegTest = ArgsManagerHelper::GetNetBoolArg(*this, "-regtest", true);
1029  bool fDevNet = ArgsManagerHelper::GetNetBoolArg(*this, "-devnet", false);
1030  bool fTestNet = ArgsManagerHelper::GetNetBoolArg(*this, "-testnet", true);
1031 
1032  int nameParamsCount = (fRegTest ? 1 : 0) + (fDevNet ? 1 : 0) + (fTestNet ? 1 : 0);
1033  if (nameParamsCount > 1)
1034  throw std::runtime_error("Only one of -regtest, -testnet or -devnet can be used.");
1035 
1036  if (fDevNet)
1037  return CBaseChainParams::DEVNET;
1038  if (fRegTest)
1040  if (fTestNet)
1042  return CBaseChainParams::MAIN;
1043 }
1044 
1045 std::string ArgsManager::GetDevNetName() const
1046 {
1047  assert(IsArgSet("-devnet"));
1048  std::string devNetName = GetArg("-devnet", "");
1049  return "devnet" + (devNetName.empty() ? "" : "-" + devNetName);
1050 }
1051 
1052 #ifndef WIN32
1053 fs::path GetPidFile()
1054 {
1055  return AbsPathForConfigVal(fs::path(gArgs.GetArg("-pid", BITCOIN_PID_FILENAME)));
1056 }
1057 
1058 void CreatePidFile(const fs::path &path, pid_t pid)
1059 {
1060  FILE* file = fsbridge::fopen(path, "w");
1061  if (file)
1062  {
1063  fprintf(file, "%d\n", pid);
1064  fclose(file);
1065  }
1066 }
1067 #endif
1068 
1069 bool RenameOver(fs::path src, fs::path dest)
1070 {
1071 #ifdef WIN32
1072  return MoveFileExA(src.string().c_str(), dest.string().c_str(),
1073  MOVEFILE_REPLACE_EXISTING) != 0;
1074 #else
1075  int rc = std::rename(src.string().c_str(), dest.string().c_str());
1076  return (rc == 0);
1077 #endif /* WIN32 */
1078 }
1079 
1085 bool TryCreateDirectories(const fs::path& p)
1086 {
1087  try
1088  {
1089  return fs::create_directories(p);
1090  } catch (const fs::filesystem_error&) {
1091  if (!fs::exists(p) || !fs::is_directory(p))
1092  throw;
1093  }
1094 
1095  // create_directories didn't create the directory, it had to have existed already
1096  return false;
1097 }
1098 
1099 void FileCommit(FILE *file)
1100 {
1101  fflush(file); // harmless if redundantly called
1102 #ifdef WIN32
1103  HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(file));
1104  FlushFileBuffers(hFile);
1105 #else
1106  #if defined(__linux__) || defined(__NetBSD__)
1107  fdatasync(fileno(file));
1108  #elif defined(__APPLE__) && defined(F_FULLFSYNC)
1109  fcntl(fileno(file), F_FULLFSYNC, 0);
1110  #else
1111  fsync(fileno(file));
1112  #endif
1113 #endif
1114 }
1115 
1116 bool TruncateFile(FILE *file, unsigned int length) {
1117 #if defined(WIN32)
1118  return _chsize(_fileno(file), length) == 0;
1119 #else
1120  return ftruncate(fileno(file), length) == 0;
1121 #endif
1122 }
1123 
1128 int RaiseFileDescriptorLimit(int nMinFD) {
1129 #if defined(WIN32)
1130  return 2048;
1131 #else
1132  struct rlimit limitFD;
1133  if (getrlimit(RLIMIT_NOFILE, &limitFD) != -1) {
1134  if (limitFD.rlim_cur < (rlim_t)nMinFD) {
1135  limitFD.rlim_cur = nMinFD;
1136  if (limitFD.rlim_cur > limitFD.rlim_max)
1137  limitFD.rlim_cur = limitFD.rlim_max;
1138  setrlimit(RLIMIT_NOFILE, &limitFD);
1139  getrlimit(RLIMIT_NOFILE, &limitFD);
1140  }
1141  return limitFD.rlim_cur;
1142  }
1143  return nMinFD; // getrlimit failed, assume it's fine
1144 #endif
1145 }
1146 
1151 void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length) {
1152 #if defined(WIN32)
1153  // Windows-specific version
1154  HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(file));
1155  LARGE_INTEGER nFileSize;
1156  int64_t nEndPos = (int64_t)offset + length;
1157  nFileSize.u.LowPart = nEndPos & 0xFFFFFFFF;
1158  nFileSize.u.HighPart = nEndPos >> 32;
1159  SetFilePointerEx(hFile, nFileSize, 0, FILE_BEGIN);
1160  SetEndOfFile(hFile);
1161 #elif defined(MAC_OSX)
1162  // OSX specific version
1163  fstore_t fst;
1164  fst.fst_flags = F_ALLOCATECONTIG;
1165  fst.fst_posmode = F_PEOFPOSMODE;
1166  fst.fst_offset = 0;
1167  fst.fst_length = (off_t)offset + length;
1168  fst.fst_bytesalloc = 0;
1169  if (fcntl(fileno(file), F_PREALLOCATE, &fst) == -1) {
1170  fst.fst_flags = F_ALLOCATEALL;
1171  fcntl(fileno(file), F_PREALLOCATE, &fst);
1172  }
1173  ftruncate(fileno(file), fst.fst_length);
1174 #elif defined(__linux__)
1175  // Version using posix_fallocate
1176  off_t nEndPos = (off_t)offset + length;
1177  posix_fallocate(fileno(file), 0, nEndPos);
1178 #else
1179  // Fallback version
1180  // TODO: just write one byte per block
1181  static const char buf[65536] = {};
1182  fseek(file, offset, SEEK_SET);
1183  while (length > 0) {
1184  unsigned int now = 65536;
1185  if (length < now)
1186  now = length;
1187  fwrite(buf, 1, now, file); // allowed to fail; this function is advisory anyway
1188  length -= now;
1189  }
1190 #endif
1191 }
1192 
1194 {
1195  // Amount of debug.log to save at end when shrinking (must fit in memory)
1196  constexpr size_t RECENT_DEBUG_HISTORY_SIZE = 10 * 1000000;
1197  // Scroll debug.log if it's getting too big
1198  fs::path pathLog = GetDebugLogPath();
1199  FILE* file = fsbridge::fopen(pathLog, "r");
1200  // If debug.log file is more than 10% bigger the RECENT_DEBUG_HISTORY_SIZE
1201  // trim it down by saving only the last RECENT_DEBUG_HISTORY_SIZE bytes
1202  if (file && fs::file_size(pathLog) > 11 * (RECENT_DEBUG_HISTORY_SIZE / 10))
1203  {
1204  // Restart the file with some of the end
1205  std::vector<char> vch(RECENT_DEBUG_HISTORY_SIZE, 0);
1206  fseek(file, -((long)vch.size()), SEEK_END);
1207  int nBytes = fread(vch.data(), 1, vch.size(), file);
1208  fclose(file);
1209 
1210  file = fsbridge::fopen(pathLog, "w");
1211  if (file)
1212  {
1213  fwrite(vch.data(), 1, nBytes, file);
1214  fclose(file);
1215  }
1216  }
1217  else if (file != nullptr)
1218  fclose(file);
1219 }
1220 
1221 #ifdef WIN32
1222 fs::path GetSpecialFolderPath(int nFolder, bool fCreate)
1223 {
1224  char pszPath[MAX_PATH] = "";
1225 
1226  if(SHGetSpecialFolderPathA(nullptr, pszPath, nFolder, fCreate))
1227  {
1228  return fs::path(pszPath);
1229  }
1230 
1231  LogPrintf("SHGetSpecialFolderPathA() failed, could not obtain requested path.\n");
1232  return fs::path("");
1233 }
1234 #endif
1235 
1236 void runCommand(const std::string& strCommand)
1237 {
1238  if (strCommand.empty()) return;
1239  int nErr = ::system(strCommand.c_str());
1240  if (nErr)
1241  LogPrintf("runCommand error: system(%s) returned %d\n", strCommand, nErr);
1242 }
1243 
1244 void RenameThread(const char* name)
1245 {
1246 #if defined(PR_SET_NAME)
1247  // Only the first 15 characters are used (16 - NUL terminator)
1248  ::prctl(PR_SET_NAME, name, 0, 0, 0);
1249 #elif (defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__))
1250  pthread_set_name_np(pthread_self(), name);
1251 
1252 #elif defined(MAC_OSX)
1253  pthread_setname_np(name);
1254 #else
1255  // Prevent warnings for unused parameters...
1256  (void)name;
1257 #endif
1258  LogPrintf("%s: thread new name %s\n", __func__, name);
1259 }
1260 
1261 std::string GetThreadName()
1262 {
1263  char name[16];
1264 #if defined(PR_GET_NAME)
1265  // Only the first 15 characters are used (16 - NUL terminator)
1266  ::prctl(PR_GET_NAME, name, 0, 0, 0);
1267 #elif defined(MAC_OSX)
1268  pthread_getname_np(pthread_self(), name, 16);
1269 // #elif (defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__))
1270 // #else
1271  // no get_name here
1272 #endif
1273  return std::string(name);
1274 }
1275 
1276 void RenameThreadPool(ctpl::thread_pool& tp, const char* baseName)
1277 {
1278  auto cond = std::make_shared<std::condition_variable>();
1279  auto mutex = std::make_shared<std::mutex>();
1280  std::atomic<int> doneCnt(0);
1281  std::map<int, std::future<void> > futures;
1282 
1283  for (int i = 0; i < tp.size(); i++) {
1284  futures[i] = tp.push([baseName, i, cond, mutex, &doneCnt](int threadId) {
1285  RenameThread(strprintf("%s-%d", baseName, i).c_str());
1286  std::unique_lock<std::mutex> l(*mutex);
1287  doneCnt++;
1288  cond->wait(l);
1289  });
1290  }
1291 
1292  do {
1293  // Always sleep to let all threads acquire locks
1294  MilliSleep(10);
1295  // `doneCnt` should be at least `futures.size()` if tp size was increased (for whatever reason),
1296  // or at least `tp.size()` if tp size was decreased and queue was cleared
1297  // (which can happen on `stop()` if we were not fast enough to get all jobs to their threads).
1298  } while (doneCnt < futures.size() && doneCnt < tp.size());
1299 
1300  cond->notify_all();
1301 
1302  // Make sure no one is left behind, just in case
1303  for (auto& pair : futures) {
1304  auto& f = pair.second;
1305  if (f.valid() && f.wait_for(std::chrono::milliseconds(2000)) == std::future_status::timeout) {
1306  LogPrintf("%s: %s-%d timed out\n", __func__, baseName, pair.first);
1307  // Notify everyone again
1308  cond->notify_all();
1309  break;
1310  }
1311  }
1312 }
1313 
1315 {
1316 #ifdef HAVE_MALLOPT_ARENA_MAX
1317  // glibc-specific: On 32-bit systems set the number of arenas to 1.
1318  // By default, since glibc 2.10, the C library will create up to two heap
1319  // arenas per core. This is known to cause excessive virtual address space
1320  // usage in our usage. Work around it by setting the maximum number of
1321  // arenas to 1.
1322  if (sizeof(void*) == 4) {
1323  mallopt(M_ARENA_MAX, 1);
1324  }
1325 #endif
1326  // On most POSIX systems (e.g. Linux, but not BSD) the environment's locale
1327  // may be invalid, in which case the "C" locale is used as fallback.
1328 #if !defined(WIN32) && !defined(MAC_OSX) && !defined(__FreeBSD__) && !defined(__OpenBSD__)
1329  try {
1330  std::locale(""); // Raises a runtime error if current locale is invalid
1331  } catch (const std::runtime_error&) {
1332  setenv("LC_ALL", "C", 1);
1333  }
1334 #endif
1335  // The path locale is lazy initialized and to avoid deinitialization errors
1336  // in multithreading environments, it is set explicitly by the main thread.
1337  // A dummy locale is used to extract the internal default locale, used by
1338  // fs::path, which is then used to explicitly imbue the path.
1339  std::locale loc = fs::path::imbue(std::locale::classic());
1340  fs::path::imbue(loc);
1341 }
1342 
1344 {
1345 #ifdef WIN32
1346  // Initialize Windows Sockets
1347  WSADATA wsadata;
1348  int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1349  if (ret != NO_ERROR || LOBYTE(wsadata.wVersion ) != 2 || HIBYTE(wsadata.wVersion) != 2)
1350  return false;
1351 #endif
1352  return true;
1353 }
1354 
1356 {
1357 #if BOOST_VERSION >= 105600
1358  return boost::thread::physical_concurrency();
1359 #else // Must fall back to hardware_concurrency, which unfortunately counts virtual cores
1360  return boost::thread::hardware_concurrency();
1361 #endif
1362 }
1363 
1364 std::string CopyrightHolders(const std::string& strPrefix, unsigned int nStartYear, unsigned int nEndYear)
1365 {
1366  std::string strCopyrightHolders = strPrefix + strprintf(" %u-%u ", nStartYear, nEndYear) + strprintf(_(COPYRIGHT_HOLDERS), _(COPYRIGHT_HOLDERS_SUBSTITUTION));
1367 
1368  // Check for untranslated substitution to make sure Dash Core copyright is not removed by accident
1369  if (strprintf(COPYRIGHT_HOLDERS, COPYRIGHT_HOLDERS_SUBSTITUTION).find("Dash Core") == std::string::npos) {
1370  strCopyrightHolders += "\n" + strPrefix + strprintf(" %u-%u ", 2014, nEndYear) + "The Dash Core developers";
1371  }
1372  // Check for untranslated substitution to make sure Bitcoin Core copyright is not removed by accident
1373  if (strprintf(COPYRIGHT_HOLDERS, COPYRIGHT_HOLDERS_SUBSTITUTION).find("Bitcoin Core") == std::string::npos) {
1374  strCopyrightHolders += "\n" + strPrefix + strprintf(" %u-%u ", 2009, nEndYear) + "The Bitcoin Core developers";
1375  }
1376  return strCopyrightHolders;
1377 }
1378 
1379 uint32_t StringVersionToInt(const std::string& strVersion)
1380 {
1381  std::vector<std::string> tokens;
1382  boost::split(tokens, strVersion, boost::is_any_of("."));
1383  if(tokens.size() != 3)
1384  throw std::bad_cast();
1385  uint32_t nVersion = 0;
1386  for(unsigned idx = 0; idx < 3; idx++)
1387  {
1388  if(tokens[idx].length() == 0)
1389  throw std::bad_cast();
1390  uint32_t value = boost::lexical_cast<uint32_t>(tokens[idx]);
1391  if(value > 255)
1392  throw std::bad_cast();
1393  nVersion <<= 8;
1394  nVersion |= value;
1395  }
1396  return nVersion;
1397 }
1398 
1399 std::string IntVersionToString(uint32_t nVersion)
1400 {
1401  if((nVersion >> 24) > 0) // MSB is always 0
1402  throw std::bad_cast();
1403  if(nVersion == 0)
1404  throw std::bad_cast();
1405  std::array<std::string, 3> tokens;
1406  for(unsigned idx = 0; idx < 3; idx++)
1407  {
1408  unsigned shift = (2 - idx) * 8;
1409  uint32_t byteValue = (nVersion >> shift) & 0xff;
1410  tokens[idx] = boost::lexical_cast<std::string>(byteValue);
1411  }
1412  return boost::join(tokens, ".");
1413 }
1414 
1415 std::string SafeIntVersionToString(uint32_t nVersion)
1416 {
1417  try
1418  {
1419  return IntVersionToString(nVersion);
1420  }
1421  catch(const std::bad_cast&)
1422  {
1423  return "invalid_version";
1424  }
1425 }
1426 
1427 
1428 // Obtain the application startup time (used for uptime calculation)
1430 {
1431  return nStartupTime;
1432 }
1433 
1434 fs::path AbsPathForConfigVal(const fs::path& path, bool net_specific)
1435 {
1436  return fs::absolute(path, GetDataDir(net_specific));
1437 }
ArgsManager()
Definition: util.cpp:681
std::string HelpMessageOpt(const std::string &option, const std::string &message)
Format a string to be used as option description in help messages.
Definition: util.cpp:884
#define NO_THREAD_SAFETY_ANALYSIS
Definition: threadsafety.h:52
std::string ListLogCategories()
Returns a string with the log categories.
Definition: util.cpp:322
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
Definition: util.cpp:784
const int64_t nStartupTime
Definition: util.cpp:90
bool SetupNetworking()
Definition: util.cpp:1343
FILE * freopen(const fs::path &p, const char *mode, FILE *stream)
Definition: fs.cpp:10
std::string ListActiveLogCategoriesString()
Returns a string with the list of active log categories.
Definition: util.cpp:352
void ParseParameters(int argc, const char *const argv[])
Definition: util.cpp:730
FILE * fopen(const fs::path &p, const char *mode)
Definition: fs.cpp:5
void MilliSleep(int64_t n)
Definition: utiltime.cpp:75
const char *const BITCOIN_CONF_FILENAME
Definition: util.cpp:104
void ReleaseDirectoryLocks()
Release all directory locks.
Definition: util.cpp:506
void FileCommit(FILE *file)
Definition: util.cpp:1099
static fs::path pathCached
Definition: util.cpp:924
bool SoftSetBoolArg(const std::string &strArg, bool fValue)
Set a boolean argument if it doesn&#39;t already have a value.
Definition: util.cpp:840
static const std::string REGTEST
const char *const BITCOIN_PID_FILENAME
Definition: util.cpp:105
#define strprintf
Definition: tinyformat.h:1066
auto push(F &&f, Rest &&... rest) -> std::future< decltype(f(0, rest...))>
Definition: ctpl.h:152
std::string DateTimeStrFormat(const char *pszFormat, int64_t nTime)
Definition: utiltime.cpp:93
static FILE * fileout
We use boost::call_once() to make sure mutexDebugLog and vMsgsBeforeOpenLog are initialized in a thre...
Definition: util.cpp:192
int64_t GetStartupTime()
Definition: util.cpp:1429
void WarnForSectionOnlyArgs()
Log warnings for options in m_section_only_args when they are specified in the default section but no...
Definition: util.cpp:697
static boost::once_flag debugPrintInitFlag
LogPrintf() has been broken a couple of times now by well-meaning people adding mutexes in the most s...
Definition: util.cpp:181
#define MAX_PATH
Definition: compat.h:84
void SelectConfigNetwork(const std::string &network)
Select the network in use.
Definition: util.cpp:725
const CBaseChainParams & BaseParams()
Return the currently selected parameters.
static bool InterpretNegatedOption(std::string &key, std::string &val)
Interpret -nofoo as if the user supplied -foo=0.
Definition: util.cpp:657
Definition: util.cpp:134
static const int msgIndent
Definition: util.cpp:878
int64_t GetTimeMicros()
Returns the system time (not mockable)
Definition: utiltime.cpp:63
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: util.cpp:824
static std::string LogThreadNameStr(const std::string &str, std::atomic_bool *fStartedNewLine)
fStartedNewLine is a state variable held by the calling context that will suppress printing of the th...
Definition: util.cpp:405
std::atomic< uint64_t > logCategories(0)
Log categories bitfield.
std::map< std::string, std::vector< std::string > > m_config_args
Definition: util.h:285
void ForceSetArg(const std::string &strArg, const std::string &strValue)
Definition: util.cpp:848
void locking_callback(int mode, int i, const char *file, int line) NO_THREAD_SAFETY_ANALYSIS
Definition: util.cpp:124
fs::path AbsPathForConfigVal(const fs::path &path, bool net_specific)
Most paths passed as configuration arguments are treated as relative to the datadir if they are not a...
Definition: util.cpp:1434
void ReadConfigFile(const std::string &confPath)
Definition: util.cpp:1000
bool SoftSetArg(const std::string &strArg, const std::string &strValue)
Set an argument if it doesn&#39;t already have a value.
Definition: util.cpp:832
static const bool DEFAULT_LOGTIMEMICROS
Definition: util.h:59
void RenameThread(const char *name)
Definition: util.cpp:1244
bool LockDirectory(const fs::path &directory, const std::string lockfile_name, bool probe_only)
Definition: util.cpp:477
static const int screenWidth
Definition: util.cpp:876
std::set< std::string > m_network_only_args
Definition: util.h:287
static std::map< std::string, std::unique_ptr< boost::interprocess::file_lock > > dir_locks
A map that contains all the currently held directory locks.
Definition: util.cpp:473
static bool LogAcceptCategory(uint64_t category)
Definition: util.h:152
const std::string & DataDir() const
static const bool DEFAULT_LOGTIMESTAMPS
Definition: util.h:61
std::string CopyrightHolders(const std::string &strPrefix, unsigned int nStartYear, unsigned int nEndYear)
Definition: util.cpp:1364
static const std::string MAIN
BIP70 chain name strings (main, test or regtest)
int RaiseFileDescriptorLimit(int nMinFD)
this function tries to raise the file descriptor limit to the requested number.
Definition: util.cpp:1128
uint32_t StringVersionToInt(const std::string &strVersion)
Converts version strings to 4-byte unsigned integer.
Definition: util.cpp:1379
class CInit instance_of_cinit
std::string SafeIntVersionToString(uint32_t nVersion)
Copy of the IntVersionToString, that returns "Invalid version" string instead of throwing std::bad_ca...
Definition: util.cpp:1415
CTranslationInterface translationInterface
Definition: util.cpp:117
int64_t GetTime()
Return system time (or mocked time, if set)
Definition: utiltime.cpp:22
bool fMasternodeMode
Definition: util.cpp:93
static const bool DEFAULT_LOGIPS
Definition: util.h:60
int nWalletBackups
nWalletBackups: 1..10 - number of automatic backups to keep 0 - disabled by command-line -1 - disable...
Definition: util.cpp:102
bool IsArgNegated(const std::string &strArg) const
Return true if the argument was originally passed as a negated option, i.e.
Definition: util.cpp:790
bool TruncateFile(FILE *file, unsigned int length)
Definition: util.cpp:1116
std::string category
Definition: util.cpp:243
#define LogPrintf(...)
Definition: util.h:203
#define LEAVE_CRITICAL_SECTION(cs)
Definition: sync.h:188
bool GetLogCategory(uint64_t *f, const std::string *str)
Return true if str parses as a log category and set the flags in f.
Definition: util.cpp:291
#define LOCK(cs)
Definition: sync.h:178
const char * name
Definition: rest.cpp:36
fs::path GetPidFile()
Definition: util.cpp:1053
static std::list< std::string > * vMsgsBeforeOpenLog
Definition: util.cpp:194
bool fLogTimeMicros
Definition: util.cpp:113
bool TryCreateDirectories(const fs::path &p)
Ignores exceptions thrown by Boost&#39;s create_directories if the requested directory exists...
Definition: util.cpp:1085
static int FileWriteStr(const std::string &str, FILE *fp)
Definition: util.cpp:196
~CInit()
Definition: util.cpp:158
void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length)
this function tries to make a particular range of a file allocated (corresponding to disk space) it i...
Definition: util.cpp:1151
static std::string NetworkArg(const ArgsManager &am, const std::string &arg)
Convert regular argument into the network-specific setting.
Definition: util.cpp:549
static const int optIndent
Definition: util.cpp:877
std::string FormatParagraph(const std::string &in, size_t width, size_t indent)
Format a paragraph of text to a fixed width, adding spaces for indentation to any added line...
CCriticalSection cs_args
Definition: util.h:283
std::string IntVersionToString(uint32_t nVersion)
Converts version as 4-byte unsigned integer to string.
Definition: util.cpp:1399
static bool UseDefaultSection(const ArgsManager &am, const std::string &arg)
Determine whether to use config settings in the default section, See also comments around ArgsManager...
Definition: util.cpp:543
std::string GetThreadName()
Definition: util.cpp:1261
static const std::string DEVNET
static CCriticalSection csPathCached
Definition: util.cpp:926
static std::pair< bool, std::string > GetArg(const ArgsManager &am, const std::string &arg)
Definition: util.cpp:586
static const bool DEFAULT_LOGTHREADNAMES
Definition: util.h:62
bool RenameOver(fs::path src, fs::path dest)
Definition: util.cpp:1069
std::map< std::string, std::vector< std::string > > MapArgs
Definition: util.cpp:539
void ForceRemoveArg(const std::string &strArg)
Definition: util.cpp:854
uint64_t flag
Definition: util.cpp:242
static std::unique_ptr< CCriticalSection[]> ppmutexOpenSSL
Init OpenSSL library multithreading support.
Definition: util.cpp:123
fs::path GetDefaultDataDir()
Definition: util.cpp:898
std::string GetPrettyExceptionStr(const std::exception_ptr &e)
static fs::path pathCachedNetSpecific
Definition: util.cpp:925
bool fLogTimestamps
Definition: util.cpp:112
static boost::mutex * mutexDebugLog
Definition: util.cpp:193
void PrintExceptionContinue(const std::exception_ptr pex, const char *pszExceptionOrigin)
Definition: util.cpp:891
#define ENTER_CRITICAL_SECTION(cs)
Definition: sync.h:182
bool fLogIPs
Definition: util.cpp:115
std::string GetDevNetName() const
Looks for -devnet and returns either "devnet-<name>" or simply "devnet" if no name was specified...
Definition: util.cpp:1045
ArgsManager gArgs
Definition: util.cpp:108
Internal helper functions for ArgsManager.
Definition: util.cpp:537
bool fPrintToConsole
Definition: util.cpp:109
static bool GetNetBoolArg(const ArgsManager &am, const std::string &net_arg, bool interpret_bool)
Definition: util.cpp:622
#define ARRAYLEN(array)
static std::string LogTimestampStr(const std::string &str, std::atomic_bool *fStartedNewLine)
fStartedNewLine is a state variable held by the calling context that will suppress printing of the ti...
Definition: util.cpp:377
fs::path GetConfigFile(const std::string &confPath)
Definition: util.cpp:976
void ReadConfigStream(std::istream &stream)
Definition: util.cpp:981
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: util.cpp:808
bool fPrintToDebugLog
Definition: util.cpp:110
void runCommand(const std::string &strCommand)
Definition: util.cpp:1236
int size()
Definition: ctpl.h:61
Signals for translation.
Definition: util.h:66
const char *const DEFAULT_DEBUGLOGFILE
Definition: util.cpp:106
void ClearDatadirCache()
Definition: util.cpp:968
std::string category
Definition: util.h:103
std::atomic< bool > fReopenDebugLog(false)
int64_t atoi64(const char *psz)
CInit()
Definition: util.cpp:137
fs::path GetBackupsDir()
Definition: util.cpp:960
void RenameThreadPool(ctpl::thread_pool &tp, const char *baseName)
Definition: util.cpp:1276
bool error(const char *fmt, const Args &... args)
Definition: util.h:222
void RandAddSeed()
Definition: random.cpp:130
static const std::string TESTNET
std::string GetChainName() const
Looks for -regtest, -testnet and returns the appropriate BIP70 chain name.
Definition: util.cpp:1026
const fs::path & GetDataDir(bool fNetSpecific)
Definition: util.cpp:928
void CreatePidFile(const fs::path &path, pid_t pid)
Definition: util.cpp:1058
static bool InterpretBool(const std::string &strValue)
Interpret a string argument as a boolean.
Definition: util.cpp:529
bool fLogThreadNames
Definition: util.cpp:114
static void DebugPrintInit()
Definition: util.cpp:201
int GetNumCores()
Return the number of physical cores available on the current system.
Definition: util.cpp:1355
int64_t GetMockTime()
For testing.
Definition: utiltime.cpp:51
static void AddArgs(std::vector< std::string > &res, const MapArgs &map_args, const std::string &arg)
Find arguments in a map and add them to a vector.
Definition: util.cpp:556
std::vector< std::string > GetArgs(const std::string &strArg) const
Return a vector of strings of the given argument.
Definition: util.cpp:765
bool OpenDebugLog()
Definition: util.cpp:214
void SetupEnvironment()
Definition: util.cpp:1314
bool fDisableGovernance
Definition: util.cpp:94
static std::mutex cs_dir_locks
Mutex to protect dir_locks.
Definition: util.cpp:475
fs::path GetDebugLogPath()
Definition: util.cpp:208
std::string HelpMessageGroup(const std::string &message)
Format a string to be used as group of options in help messages.
Definition: util.cpp:880
std::string m_network
Definition: util.h:286
int LogPrintStr(const std::string &str)
Send a string to the log output.
Definition: util.cpp:422
std::vector< CLogCategoryActive > ListActiveLogCategories()
Returns a vector of the active log categories.
Definition: util.cpp:337
std::map< std::string, std::vector< std::string > > m_override_args
Definition: util.h:284
void ShrinkDebugFile()
Definition: util.cpp:1193
std::string _(const char *psz)
Translation function: Call Translate signal on UI interface, which returns a boost::optional result...
Definition: util.h:92
const CLogCategoryDesc LogCategories[]
Definition: util.cpp:246
Wrapped mutex: supports recursive locking, but no waiting TODO: We should move away from using the re...
Definition: sync.h:94
int atoi(const std::string &str)
static std::pair< bool, std::string > GetArgHelper(const MapArgs &map_args, const std::string &arg, bool getLast=false)
Return true/false if an argument is set in a map, and also return the first (or last) of the possibly...
Definition: util.cpp:567
Released under the MIT license