1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
8 map<string, string> mapArgs;
9 map<string, vector<string> > mapMultiArgs;
11 bool fPrintToConsole = false;
12 bool fPrintToDebugger = false;
13 char pszSetDataDir[MAX_PATH] = "";
14 bool fShutdown = false;
16 bool fCommandLine = false;
22 // Init openssl library multithreading support
23 static boost::interprocess::interprocess_mutex** ppmutexOpenSSL;
24 void locking_callback(int mode, int i, const char* file, int line)
26 if (mode & CRYPTO_LOCK)
27 ppmutexOpenSSL[i]->lock();
29 ppmutexOpenSSL[i]->unlock();
38 // Init openssl library multithreading support
39 ppmutexOpenSSL = (boost::interprocess::interprocess_mutex**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(boost::interprocess::interprocess_mutex*));
40 for (int i = 0; i < CRYPTO_num_locks(); i++)
41 ppmutexOpenSSL[i] = new boost::interprocess::interprocess_mutex();
42 CRYPTO_set_locking_callback(locking_callback);
45 // Seed random number generator with screen scrape and other hardware sources
49 // Seed random number generator with performance counter
54 // Shutdown openssl library multithreading support
55 CRYPTO_set_locking_callback(NULL);
56 for (int i = 0; i < CRYPTO_num_locks(); i++)
57 delete ppmutexOpenSSL[i];
58 OPENSSL_free(ppmutexOpenSSL);
72 // Seed with CPU performance counter
73 int64 nCounter = PerformanceCounter();
74 RAND_add(&nCounter, sizeof(nCounter), 1.5);
75 memset(&nCounter, 0, sizeof(nCounter));
78 void RandAddSeedPerfmon()
82 // This can take up to 2 seconds, so only do it every 10 minutes
83 static int64 nLastPerfmon;
84 if (GetTime() < nLastPerfmon + 10 * 60)
86 nLastPerfmon = GetTime();
89 // Don't need this on Linux, OpenSSL automatically uses /dev/urandom
90 // Seed with the entire set of perfmon data
91 unsigned char pdata[250000];
92 memset(pdata, 0, sizeof(pdata));
93 unsigned long nSize = sizeof(pdata);
94 long ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize);
95 RegCloseKey(HKEY_PERFORMANCE_DATA);
96 if (ret == ERROR_SUCCESS)
99 SHA256(pdata, nSize, (unsigned char*)&hash);
100 RAND_add(&hash, sizeof(hash), min(nSize/500.0, (double)sizeof(hash)));
102 memset(pdata, 0, nSize);
104 printf("%s RandAddSeed() %d bytes\n", DateTimeStrFormat("%x %H:%M", GetTime()).c_str(), nSize);
109 uint64 GetRand(uint64 nMax)
114 // The range of the random source must be a multiple of the modulus
115 // to give every possible output value an equal possibility
116 uint64 nRange = (UINT64_MAX / nMax) * nMax;
119 RAND_bytes((unsigned char*)&nRand, sizeof(nRand));
120 while (nRand >= nRange);
121 return (nRand % nMax);
134 inline int OutputDebugStringF(const char* pszFormat, ...)
137 if (fPrintToConsole || wxTheApp == NULL)
141 va_start(arg_ptr, pszFormat);
142 ret = vprintf(pszFormat, arg_ptr);
147 // print to debug.log
148 char pszFile[MAX_PATH+100];
150 strlcat(pszFile, "/debug.log", sizeof(pszFile));
151 FILE* fileout = fopen(pszFile, "a");
154 //// Debug print useful for profiling
155 //fprintf(fileout, " %"PRI64d" ", GetTimeMillis());
157 va_start(arg_ptr, pszFormat);
158 ret = vfprintf(fileout, pszFormat, arg_ptr);
165 if (fPrintToDebugger)
167 // accumulate a line at a time
168 static CCriticalSection cs_OutputDebugStringF;
169 CRITICAL_BLOCK(cs_OutputDebugStringF)
171 static char pszBuffer[50000];
176 va_start(arg_ptr, pszFormat);
177 int limit = END(pszBuffer) - pend - 2;
178 int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr);
180 if (ret < 0 || ret >= limit)
182 pend = END(pszBuffer) - 2;
188 char* p1 = pszBuffer;
190 while (p2 = strchr(p1, '\n'))
195 OutputDebugStringA(p1);
200 memmove(pszBuffer, p1, pend - p1 + 1);
201 pend -= (p1 - pszBuffer);
210 // - prints up to limit-1 characters
211 // - output string is always null terminated even if limit reached
212 // - return value is the number of characters actually printed
213 int my_snprintf(char* buffer, size_t limit, const char* format, ...)
218 va_start(arg_ptr, format);
219 int ret = _vsnprintf(buffer, limit, format, arg_ptr);
221 if (ret < 0 || ret >= limit)
230 string strprintf(const char* format, ...)
234 int limit = sizeof(buffer);
239 va_start(arg_ptr, format);
240 ret = _vsnprintf(p, limit, format, arg_ptr);
242 if (ret >= 0 && ret < limit)
249 throw std::bad_alloc();
251 string str(p, p+ret);
258 bool error(const char* format, ...)
261 int limit = sizeof(buffer);
263 va_start(arg_ptr, format);
264 int ret = _vsnprintf(buffer, limit, format, arg_ptr);
266 if (ret < 0 || ret >= limit)
271 printf("ERROR: %s\n", buffer);
276 void ParseString(const string& str, char c, vector<string>& v)
280 string::size_type i1 = 0;
281 string::size_type i2;
284 i2 = str.find(c, i1);
287 v.push_back(str.substr(i1));
290 v.push_back(str.substr(i1, i2-i1));
296 string FormatMoney(int64 n, bool fPlus)
299 string str = strprintf("%"PRI64d".%02"PRI64d, (n > 0 ? n : -n)/100, (n > 0 ? n : -n)%100);
300 for (int i = 6; i < str.size(); i += 4)
301 if (isdigit(str[str.size() - i - 1]))
302 str.insert(str.size() - i, 1, ',');
304 str.insert((unsigned int)0, 1, '-');
305 else if (fPlus && n > 0)
306 str.insert((unsigned int)0, 1, '+');
311 bool ParseMoney(const string& str, int64& nRet)
313 return ParseMoney(str.c_str(), nRet);
316 bool ParseMoney(const char* pszIn, int64& nRet)
320 const char* p = pszIn;
325 if (*p == ',' && p > pszIn && isdigit(p[-1]) && isdigit(p[1]) && isdigit(p[2]) && isdigit(p[3]) && !isdigit(p[4]))
332 nCents = 10 * (*p++ - '0');
334 nCents += (*p++ - '0');
342 strWhole.insert(strWhole.end(), *p);
347 if (strWhole.size() > 14)
349 if (nCents < 0 || nCents > 99)
351 int64 nWhole = atoi64(strWhole);
352 int64 nPreValue = nWhole * 100 + nCents;
353 int64 nValue = nPreValue * CENT;
354 if (nValue / CENT != nPreValue)
356 if (nValue / COIN != nWhole)
363 vector<unsigned char> ParseHex(const char* psz)
365 vector<unsigned char> vch;
366 while (isspace(*psz))
368 vch.reserve((strlen(psz)+1)/3);
370 static char phexdigit[256] =
371 { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
372 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
373 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
374 0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,
375 -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
376 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
377 -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1
378 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
379 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
380 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
381 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
382 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
383 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
384 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
385 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
386 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, };
390 char c = phexdigit[(unsigned char)*psz++];
393 unsigned char n = (c << 4);
396 char c = phexdigit[(unsigned char)*psz++];
402 while (isspace(*psz))
409 vector<unsigned char> ParseHex(const std::string& str)
411 return ParseHex(str.c_str());
415 void ParseParameters(int argc, char* argv[])
418 mapMultiArgs.clear();
419 for (int i = 1; i < argc; i++)
422 strlcpy(psz, argv[i], sizeof(psz));
423 char* pszValue = (char*)"";
424 if (strchr(psz, '='))
426 pszValue = strchr(psz, '=');
436 mapArgs[psz] = pszValue;
437 mapMultiArgs[psz].push_back(pszValue);
442 const char* wxGetTranslation(const char* pszEnglish)
444 // Wrapper of wxGetTranslation returning the same const char* type as was passed in
445 static CCriticalSection cs;
449 static map<string, char*> mapCache;
450 map<string, char*>::iterator mi = mapCache.find(pszEnglish);
451 if (mi != mapCache.end())
454 // wxWidgets translation
455 wxString strTranslated = wxGetTranslation(wxString(pszEnglish, wxConvUTF8));
457 // We don't cache unknown strings because caller might be passing in a
458 // dynamic string and we would keep allocating memory for each variation.
459 if (strcmp(pszEnglish, strTranslated.utf8_str()) == 0)
462 // Add to cache, memory doesn't need to be freed. We only cache because
463 // we must pass back a pointer to permanently allocated memory.
464 char* pszCached = new char[strlen(strTranslated.utf8_str())+1];
465 strcpy(pszCached, strTranslated.utf8_str());
466 mapCache[pszEnglish] = pszCached;
481 void FormatException(char* pszMessage, std::exception* pex, const char* pszThread)
484 char pszModule[MAX_PATH];
486 GetModuleFileNameA(NULL, pszModule, sizeof(pszModule));
488 // might not be thread safe, uses wxString
489 //const char* pszModule = wxStandardPaths::Get().GetExecutablePath().mb_str();
490 const char* pszModule = "bitcoin";
493 snprintf(pszMessage, 1000,
494 "EXCEPTION: %s \n%s \n%s in %s \n", typeid(*pex).name(), pex->what(), pszModule, pszThread);
496 snprintf(pszMessage, 1000,
497 "UNKNOWN EXCEPTION \n%s in %s \n", pszModule, pszThread);
500 void LogException(std::exception* pex, const char* pszThread)
502 char pszMessage[1000];
503 FormatException(pszMessage, pex, pszThread);
504 printf("\n%s", pszMessage);
507 void PrintException(std::exception* pex, const char* pszThread)
509 char pszMessage[1000];
510 FormatException(pszMessage, pex, pszThread);
511 printf("\n\n************************\n%s\n", pszMessage);
512 fprintf(stderr, "\n\n************************\n%s\n", pszMessage);
513 if (wxTheApp && !fDaemon && fGUI)
514 MyMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR);
527 typedef WINSHELLAPI BOOL (WINAPI *PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate);
529 string MyGetSpecialFolderPath(int nFolder, bool fCreate)
531 char pszPath[MAX_PATH+100] = "";
533 // SHGetSpecialFolderPath isn't always available on old Windows versions
534 HMODULE hShell32 = LoadLibraryA("shell32.dll");
537 PSHGETSPECIALFOLDERPATHA pSHGetSpecialFolderPath =
538 (PSHGETSPECIALFOLDERPATHA)GetProcAddress(hShell32, "SHGetSpecialFolderPathA");
539 if (pSHGetSpecialFolderPath)
540 (*pSHGetSpecialFolderPath)(NULL, pszPath, nFolder, fCreate);
541 FreeModule(hShell32);
545 if (pszPath[0] == '\0')
547 if (nFolder == CSIDL_STARTUP)
549 strcpy(pszPath, getenv("USERPROFILE"));
550 strcat(pszPath, "\\Start Menu\\Programs\\Startup");
552 else if (nFolder == CSIDL_APPDATA)
554 strcpy(pszPath, getenv("APPDATA"));
562 string GetDefaultDataDir()
564 // Windows: C:\Documents and Settings\username\Application Data\Bitcoin
565 // Mac: ~/Library/Application Support/Bitcoin
569 return MyGetSpecialFolderPath(CSIDL_APPDATA, true) + "\\Bitcoin";
571 char* pszHome = getenv("HOME");
572 if (pszHome == NULL || strlen(pszHome) == 0)
573 pszHome = (char*)"/";
574 string strHome = pszHome;
575 if (strHome[strHome.size()-1] != '/')
579 strHome += "Library/Application Support/";
580 _mkdir(strHome.c_str());
581 return strHome + "Bitcoin";
584 return strHome + ".bitcoin";
589 void GetDataDir(char* pszDir)
591 // pszDir must be at least MAX_PATH length.
592 if (pszSetDataDir[0] != 0)
594 strlcpy(pszDir, pszSetDataDir, MAX_PATH);
595 static bool fMkdirDone;
604 // This can be called during exceptions by printf, so we cache the
605 // value so we don't have to do memory allocations after that.
606 static char pszCachedDir[MAX_PATH];
607 if (pszCachedDir[0] == 0)
609 //strlcpy(pszCachedDir, wxStandardPaths::Get().GetUserDataDir().c_str(), sizeof(pszCachedDir));
610 strlcpy(pszCachedDir, GetDefaultDataDir().c_str(), sizeof(pszCachedDir));
611 _mkdir(pszCachedDir);
613 strlcpy(pszDir, pszCachedDir, MAX_PATH);
619 char pszDir[MAX_PATH];
624 string GetConfigFile()
626 namespace fs = boost::filesystem;
627 fs::path pathConfig(mapArgs.count("-conf") ? mapArgs["-conf"] : string("bitcoin.conf"));
628 if (!pathConfig.is_complete())
629 pathConfig = fs::path(GetDataDir()) / pathConfig;
630 return pathConfig.string();
633 void ReadConfigFile(map<string, string>& mapSettingsRet,
634 map<string, vector<string> >& mapMultiSettingsRet)
636 namespace fs = boost::filesystem;
637 namespace pod = boost::program_options::detail;
639 fs::ifstream streamConfig(GetConfigFile());
640 if (!streamConfig.good())
643 set<string> setOptions;
644 setOptions.insert("*");
646 for (pod::config_file_iterator it(streamConfig, setOptions), end; it != end; ++it)
648 // Don't overwrite existing settings so command line settings override bitcoin.conf
649 string strKey = string("-") + it->string_key;
650 if (mapSettingsRet.count(strKey) == 0)
651 mapSettingsRet[strKey] = it->value[0];
652 mapMultiSettingsRet[strKey].push_back(it->value[0]);
656 int GetFilesize(FILE* file)
658 int nSavePos = ftell(file);
660 if (fseek(file, 0, SEEK_END) == 0)
661 nFilesize = ftell(file);
662 fseek(file, nSavePos, SEEK_SET);
666 void ShrinkDebugFile()
668 // Scroll debug.log if it's getting too big
669 string strFile = GetDataDir() + "/debug.log";
670 FILE* file = fopen(strFile.c_str(), "r");
671 if (file && GetFilesize(file) > 10 * 1000000)
673 // Restart the file with some of the end
675 fseek(file, -sizeof(pch), SEEK_END);
676 int nBytes = fread(pch, 1, sizeof(pch), file);
678 if (file = fopen(strFile.c_str(), "w"))
680 fwrite(pch, 1, nBytes, file);
694 // "Never go to sea with two chronometers; take one or three."
695 // Our three chronometers are:
697 // - Median of other server's clocks
700 // note: NTP isn't implemented yet, so until then we just use the median
701 // of other nodes clocks to correct ours.
708 static int64 nTimeOffset = 0;
710 int64 GetAdjustedTime()
712 return GetTime() + nTimeOffset;
715 void AddTimeData(unsigned int ip, int64 nTime)
717 int64 nOffsetSample = nTime - GetTime();
720 static set<unsigned int> setKnown;
721 if (!setKnown.insert(ip).second)
725 static vector<int64> vTimeOffsets;
726 if (vTimeOffsets.empty())
727 vTimeOffsets.push_back(0);
728 vTimeOffsets.push_back(nOffsetSample);
729 printf("Added time data, samples %d, offset %+"PRI64d" (%+"PRI64d" minutes)\n", vTimeOffsets.size(), vTimeOffsets.back(), vTimeOffsets.back()/60);
730 if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1)
732 sort(vTimeOffsets.begin(), vTimeOffsets.end());
733 int64 nMedian = vTimeOffsets[vTimeOffsets.size()/2];
734 nTimeOffset = nMedian;
735 if ((nMedian > 0 ? nMedian : -nMedian) > 36 * 60 * 60)
737 // Only let other nodes change our clock so far before we
738 // go to the NTP servers
739 /// todo: Get time from NTP servers, then set a flag
740 /// to make sure it doesn't get changed again
743 foreach(int64 n, vTimeOffsets)
744 printf("%+"PRI64d" ", n);
745 printf("| nTimeOffset = %+"PRI64d" (%+"PRI64d" minutes)\n", nTimeOffset, nTimeOffset/60);