diff options
| author | Bitflash-sh <btf01@proton.me> | 2026-07-24 11:18:11 -0300 |
|---|---|---|
| committer | Bitflash-sh <btf01@proton.me> | 2026-07-24 11:18:11 -0300 |
| commit | 51d617e70f90a972185917ea0096c1ecef2bfa8b (patch) | |
| tree | 9fbbcd867de9de9d0776afdd02f594ba312c46eb /src/util.h | |
Bitflash: fair-launch release
Satoshi's bitcoin-0.1.0 reborn with RandomX CPU proof of work, anonymous .btf
addressing over Nostr with CGNAT rendezvous, automatic peer discovery, a
headless Linux node, and Windows GUI wallet. Fair launch, no premine, 21M cap.
Diffstat (limited to 'src/util.h')
| -rw-r--r-- | src/util.h | 413 |
1 files changed, 413 insertions, 0 deletions
diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..96cb4d4 --- /dev/null +++ b/src/util.h | |||
| @@ -0,0 +1,413 @@ | |||
| 1 | // Copyright (c) 2009 Satoshi Nakamoto | ||
| 2 | // Distributed under the MIT/X11 software license, see the accompanying | ||
| 3 | // file license.txt or http://www.opensource.org/licenses/mit-license.php. | ||
| 4 | |||
| 5 | |||
| 6 | #if defined(_MSC_VER) || defined(__BORLANDC__) | ||
| 7 | typedef __int64 int64; | ||
| 8 | typedef unsigned __int64 uint64; | ||
| 9 | #else | ||
| 10 | typedef long long int64; | ||
| 11 | typedef unsigned long long uint64; | ||
| 12 | #endif | ||
| 13 | #if defined(_MSC_VER) && _MSC_VER < 1300 | ||
| 14 | #define for if (false) ; else for | ||
| 15 | #endif | ||
| 16 | |||
| 17 | #ifndef _MSC_VER | ||
| 18 | #define __forceinline inline | ||
| 19 | #endif | ||
| 20 | |||
| 21 | #define foreach BOOST_FOREACH | ||
| 22 | #define loop for (;;) | ||
| 23 | #define BEGIN(a) ((char*)&(a)) | ||
| 24 | #define END(a) ((char*)&((&(a))[1])) | ||
| 25 | #define UBEGIN(a) ((unsigned char*)&(a)) | ||
| 26 | #define UEND(a) ((unsigned char*)&((&(a))[1])) | ||
| 27 | #define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0])) | ||
| 28 | |||
| 29 | // Route printf to debug.log (and the console) on the GUI Windows build and on | ||
| 30 | // the headless Linux build alike. | ||
| 31 | #if defined(_WINDOWS) || !defined(_WIN32) | ||
| 32 | #define printf OutputDebugStringF | ||
| 33 | #endif | ||
| 34 | |||
| 35 | #ifdef snprintf | ||
| 36 | #undef snprintf | ||
| 37 | #endif | ||
| 38 | #define snprintf my_snprintf | ||
| 39 | |||
| 40 | #ifndef PRId64 | ||
| 41 | #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MSVCRT__) | ||
| 42 | #define PRId64 "I64d" | ||
| 43 | #define PRIu64 "I64u" | ||
| 44 | #define PRIx64 "I64x" | ||
| 45 | #else | ||
| 46 | #define PRId64 "lld" | ||
| 47 | #define PRIu64 "llu" | ||
| 48 | #define PRIx64 "llx" | ||
| 49 | #endif | ||
| 50 | #endif | ||
| 51 | |||
| 52 | // This is needed because the foreach macro can't get over the comma in pair<t1, t2> | ||
| 53 | #define PAIRTYPE(t1, t2) pair<t1, t2> | ||
| 54 | |||
| 55 | // Used to bypass the rule against non-const reference to temporary | ||
| 56 | // where it makes sense with wrappers such as CFlatData or CTxDB | ||
| 57 | template<typename T> | ||
| 58 | inline T& REF(const T& val) | ||
| 59 | { | ||
| 60 | return (T&)val; | ||
| 61 | } | ||
| 62 | |||
| 63 | |||
| 64 | |||
| 65 | |||
| 66 | |||
| 67 | |||
| 68 | |||
| 69 | |||
| 70 | |||
| 71 | extern bool fDebug; | ||
| 72 | |||
| 73 | void RandAddSeed(bool fPerfmon=false); | ||
| 74 | int my_snprintf(char* buffer, size_t limit, const char* format, ...); | ||
| 75 | string strprintf(const char* format, ...); | ||
| 76 | bool error(const char* format, ...); | ||
| 77 | void PrintException(std::exception* pex, const char* pszThread); | ||
| 78 | void ParseString(const string& str, char c, vector<string>& v); | ||
| 79 | string FormatMoney(int64 n, bool fPlus=false); | ||
| 80 | bool ParseMoney(const char* pszIn, int64& nRet); | ||
| 81 | bool FileExists(const char* psz); | ||
| 82 | int GetFilesize(FILE* file); | ||
| 83 | uint64 GetRand(uint64 nMax); | ||
| 84 | int64 GetTime(); | ||
| 85 | int64 GetAdjustedTime(); | ||
| 86 | void AddTimeData(unsigned int ip, int64 nTime); | ||
| 87 | |||
| 88 | |||
| 89 | |||
| 90 | |||
| 91 | |||
| 92 | |||
| 93 | |||
| 94 | |||
| 95 | |||
| 96 | |||
| 97 | |||
| 98 | |||
| 99 | // Wrapper to automatically initialize critical section | ||
| 100 | // Could use wxCriticalSection for portability, but it doesn't support TryEnterCriticalSection | ||
| 101 | class CCriticalSection | ||
| 102 | { | ||
| 103 | protected: | ||
| 104 | CRITICAL_SECTION cs; | ||
| 105 | public: | ||
| 106 | char* pszFile; | ||
| 107 | int nLine; | ||
| 108 | explicit CCriticalSection() { InitializeCriticalSection(&cs); } | ||
| 109 | ~CCriticalSection() { DeleteCriticalSection(&cs); } | ||
| 110 | void Enter() { EnterCriticalSection(&cs); } | ||
| 111 | void Leave() { LeaveCriticalSection(&cs); } | ||
| 112 | bool TryEnter() { return TryEnterCriticalSection(&cs); } | ||
| 113 | CRITICAL_SECTION* operator&() { return &cs; } | ||
| 114 | }; | ||
| 115 | |||
| 116 | // Automatically leave critical section when leaving block, needed for exception safety | ||
| 117 | class CCriticalBlock | ||
| 118 | { | ||
| 119 | protected: | ||
| 120 | CRITICAL_SECTION* pcs; | ||
| 121 | public: | ||
| 122 | CCriticalBlock(CRITICAL_SECTION& csIn) { pcs = &csIn; EnterCriticalSection(pcs); } | ||
| 123 | CCriticalBlock(CCriticalSection& csIn) { pcs = &csIn; EnterCriticalSection(pcs); } | ||
| 124 | ~CCriticalBlock() { LeaveCriticalSection(pcs); } | ||
| 125 | }; | ||
| 126 | |||
| 127 | // WARNING: This will catch continue and break! | ||
| 128 | // break is caught with an assertion, but there's no way to detect continue. | ||
| 129 | // I'd rather be careful than suffer the other more error prone syntax. | ||
| 130 | // The compiler will optimise away all this loop junk. | ||
| 131 | #define CRITICAL_BLOCK(cs) \ | ||
| 132 | for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by CRITICAL_BLOCK!", !fcriticalblockonce)), fcriticalblockonce=false) \ | ||
| 133 | for (CCriticalBlock criticalblock(cs); fcriticalblockonce && (cs.pszFile=__FILE__, cs.nLine=__LINE__, true); fcriticalblockonce=false, cs.pszFile=NULL, cs.nLine=0) | ||
| 134 | |||
| 135 | class CTryCriticalBlock | ||
| 136 | { | ||
| 137 | protected: | ||
| 138 | CRITICAL_SECTION* pcs; | ||
| 139 | public: | ||
| 140 | CTryCriticalBlock(CRITICAL_SECTION& csIn) { pcs = (TryEnterCriticalSection(&csIn) ? &csIn : NULL); } | ||
| 141 | CTryCriticalBlock(CCriticalSection& csIn) { pcs = (TryEnterCriticalSection(&csIn) ? &csIn : NULL); } | ||
| 142 | ~CTryCriticalBlock() { if (pcs) LeaveCriticalSection(pcs); } | ||
| 143 | bool Entered() { return pcs != NULL; } | ||
| 144 | }; | ||
| 145 | |||
| 146 | #define TRY_CRITICAL_BLOCK(cs) \ | ||
| 147 | for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by TRY_CRITICAL_BLOCK!", !fcriticalblockonce)), fcriticalblockonce=false) \ | ||
| 148 | for (CTryCriticalBlock criticalblock(cs); fcriticalblockonce && (fcriticalblockonce = criticalblock.Entered()) && (cs.pszFile=__FILE__, cs.nLine=__LINE__, true); fcriticalblockonce=false, cs.pszFile=NULL, cs.nLine=0) | ||
| 149 | |||
| 150 | |||
| 151 | |||
| 152 | |||
| 153 | |||
| 154 | |||
| 155 | |||
| 156 | |||
| 157 | |||
| 158 | |||
| 159 | |||
| 160 | |||
| 161 | inline string i64tostr(int64 n) | ||
| 162 | { | ||
| 163 | return strprintf("%" PRId64, n); | ||
| 164 | } | ||
| 165 | |||
| 166 | inline string itostr(int n) | ||
| 167 | { | ||
| 168 | return strprintf("%d", n); | ||
| 169 | } | ||
| 170 | |||
| 171 | inline int64 atoi64(const char* psz) | ||
| 172 | { | ||
| 173 | #ifdef _MSC_VER | ||
| 174 | return _atoi64(psz); | ||
| 175 | #else | ||
| 176 | return strtoll(psz, NULL, 10); | ||
| 177 | #endif | ||
| 178 | } | ||
| 179 | |||
| 180 | inline int64 atoi64(const string& str) | ||
| 181 | { | ||
| 182 | #ifdef _MSC_VER | ||
| 183 | return _atoi64(str.c_str()); | ||
| 184 | #else | ||
| 185 | return strtoll(str.c_str(), NULL, 10); | ||
| 186 | #endif | ||
| 187 | } | ||
| 188 | |||
| 189 | inline int atoi(const string& str) | ||
| 190 | { | ||
| 191 | return atoi(str.c_str()); | ||
| 192 | } | ||
| 193 | |||
| 194 | inline int roundint(double d) | ||
| 195 | { | ||
| 196 | return (int)(d > 0 ? d + 0.5 : d - 0.5); | ||
| 197 | } | ||
| 198 | |||
| 199 | template<typename T> | ||
| 200 | string HexStr(const T itbegin, const T itend, bool fSpaces=true) | ||
| 201 | { | ||
| 202 | const unsigned char* pbegin = (const unsigned char*)&itbegin[0]; | ||
| 203 | const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]); | ||
| 204 | string str; | ||
| 205 | for (const unsigned char* p = pbegin; p != pend; p++) | ||
| 206 | str += strprintf((fSpaces && p != pend-1 ? "%02x " : "%02x"), *p); | ||
| 207 | return str; | ||
| 208 | } | ||
| 209 | |||
| 210 | template<typename T> | ||
| 211 | string HexNumStr(const T itbegin, const T itend, bool f0x=true) | ||
| 212 | { | ||
| 213 | const unsigned char* pbegin = (const unsigned char*)&itbegin[0]; | ||
| 214 | const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]); | ||
| 215 | string str = (f0x ? "0x" : ""); | ||
| 216 | for (const unsigned char* p = pend-1; p >= pbegin; p--) | ||
| 217 | str += strprintf("%02X", *p); | ||
| 218 | return str; | ||
| 219 | } | ||
| 220 | |||
| 221 | template<typename T> | ||
| 222 | void PrintHex(const T pbegin, const T pend, const char* pszFormat="%s", bool fSpaces=true) | ||
| 223 | { | ||
| 224 | printf(pszFormat, HexStr(pbegin, pend, fSpaces).c_str()); | ||
| 225 | } | ||
| 226 | |||
| 227 | |||
| 228 | |||
| 229 | |||
| 230 | |||
| 231 | |||
| 232 | |||
| 233 | |||
| 234 | inline int OutputDebugStringF(const char* pszFormat, ...) | ||
| 235 | { | ||
| 236 | #if 1 // debug.log always enabled (was previously only under __WXDEBUG__) | ||
| 237 | // log file | ||
| 238 | FILE* fileout = fopen("debug.log", "a"); | ||
| 239 | if (fileout) | ||
| 240 | { | ||
| 241 | va_list arg_ptr; | ||
| 242 | va_start(arg_ptr, pszFormat); | ||
| 243 | vfprintf(fileout, pszFormat, arg_ptr); | ||
| 244 | va_end(arg_ptr); | ||
| 245 | fclose(fileout); | ||
| 246 | } | ||
| 247 | |||
| 248 | #ifndef _WIN32 | ||
| 249 | // Headless build: also echo to the console (the Windows path below returns | ||
| 250 | // early before reaching the console print, which is fine for the GUI app). | ||
| 251 | { | ||
| 252 | va_list arg_ptr; | ||
| 253 | va_start(arg_ptr, pszFormat); | ||
| 254 | vprintf(pszFormat, arg_ptr); | ||
| 255 | va_end(arg_ptr); | ||
| 256 | fflush(stdout); | ||
| 257 | } | ||
| 258 | #endif | ||
| 259 | |||
| 260 | // accumulate a line at a time | ||
| 261 | static CCriticalSection cs_OutputDebugStringF; | ||
| 262 | CRITICAL_BLOCK(cs_OutputDebugStringF) | ||
| 263 | { | ||
| 264 | static char pszBuffer[50000]; | ||
| 265 | static char* pend; | ||
| 266 | if (pend == NULL) | ||
| 267 | pend = pszBuffer; | ||
| 268 | va_list arg_ptr; | ||
| 269 | va_start(arg_ptr, pszFormat); | ||
| 270 | int limit = END(pszBuffer) - pend - 2; | ||
| 271 | int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr); | ||
| 272 | va_end(arg_ptr); | ||
| 273 | if (ret < 0 || ret >= limit) | ||
| 274 | { | ||
| 275 | pend = END(pszBuffer) - 2; | ||
| 276 | *pend++ = '\n'; | ||
| 277 | } | ||
| 278 | else | ||
| 279 | pend += ret; | ||
| 280 | *pend = '\0'; | ||
| 281 | char* p1 = pszBuffer; | ||
| 282 | char* p2; | ||
| 283 | while (p2 = strchr(p1, '\n')) | ||
| 284 | { | ||
| 285 | p2++; | ||
| 286 | char c = *p2; | ||
| 287 | *p2 = '\0'; | ||
| 288 | OutputDebugStringA(p1); | ||
| 289 | *p2 = c; | ||
| 290 | p1 = p2; | ||
| 291 | } | ||
| 292 | if (p1 != pszBuffer) | ||
| 293 | memmove(pszBuffer, p1, pend - p1 + 1); | ||
| 294 | pend -= (p1 - pszBuffer); | ||
| 295 | return ret; | ||
| 296 | } | ||
| 297 | #endif | ||
| 298 | |||
| 299 | if (!wxTheApp) | ||
| 300 | { | ||
| 301 | // print to console | ||
| 302 | va_list arg_ptr; | ||
| 303 | va_start(arg_ptr, pszFormat); | ||
| 304 | vprintf(pszFormat, arg_ptr); | ||
| 305 | va_end(arg_ptr); | ||
| 306 | } | ||
| 307 | return 0; | ||
| 308 | } | ||
| 309 | |||
| 310 | |||
| 311 | |||
| 312 | |||
| 313 | |||
| 314 | |||
| 315 | |||
| 316 | |||
| 317 | |||
| 318 | inline void heapchk() | ||
| 319 | { | ||
| 320 | if (_heapchk() != _HEAPOK) | ||
| 321 | DebugBreak(); | ||
| 322 | } | ||
| 323 | |||
| 324 | // Randomize the stack to help protect against buffer overrun exploits | ||
| 325 | #define IMPLEMENT_RANDOMIZE_STACK(ThreadFn) \ | ||
| 326 | { \ | ||
| 327 | static char nLoops; \ | ||
| 328 | if (nLoops <= 0) \ | ||
| 329 | nLoops = GetRand(50) + 1; \ | ||
| 330 | if (nLoops-- > 1) \ | ||
| 331 | { \ | ||
| 332 | ThreadFn; \ | ||
| 333 | return; \ | ||
| 334 | } \ | ||
| 335 | } | ||
| 336 | |||
| 337 | #define CATCH_PRINT_EXCEPTION(pszFn) \ | ||
| 338 | catch (std::exception& e) { \ | ||
| 339 | PrintException(&e, (pszFn)); \ | ||
| 340 | } catch (...) { \ | ||
| 341 | PrintException(NULL, (pszFn)); \ | ||
| 342 | } | ||
| 343 | |||
| 344 | |||
| 345 | |||
| 346 | |||
| 347 | |||
| 348 | |||
| 349 | |||
| 350 | |||
| 351 | |||
| 352 | template<typename T1> | ||
| 353 | inline uint256 Hash(const T1 pbegin, const T1 pend) | ||
| 354 | { | ||
| 355 | uint256 hash1; | ||
| 356 | SHA256((unsigned char*)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1); | ||
| 357 | uint256 hash2; | ||
| 358 | SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); | ||
| 359 | return hash2; | ||
| 360 | } | ||
| 361 | |||
| 362 | template<typename T1, typename T2> | ||
| 363 | inline uint256 Hash(const T1 p1begin, const T1 p1end, | ||
| 364 | const T2 p2begin, const T2 p2end) | ||
| 365 | { | ||
| 366 | uint256 hash1; | ||
| 367 | SHA256_CTX ctx; | ||
| 368 | SHA256_Init(&ctx); | ||
| 369 | SHA256_Update(&ctx, (unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0])); | ||
| 370 | SHA256_Update(&ctx, (unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0])); | ||
| 371 | SHA256_Final((unsigned char*)&hash1, &ctx); | ||
| 372 | uint256 hash2; | ||
| 373 | SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); | ||
| 374 | return hash2; | ||
| 375 | } | ||
| 376 | |||
| 377 | template<typename T1, typename T2, typename T3> | ||
| 378 | inline uint256 Hash(const T1 p1begin, const T1 p1end, | ||
| 379 | const T2 p2begin, const T2 p2end, | ||
| 380 | const T3 p3begin, const T3 p3end) | ||
| 381 | { | ||
| 382 | uint256 hash1; | ||
| 383 | SHA256_CTX ctx; | ||
| 384 | SHA256_Init(&ctx); | ||
| 385 | SHA256_Update(&ctx, (unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0])); | ||
| 386 | SHA256_Update(&ctx, (unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0])); | ||
| 387 | SHA256_Update(&ctx, (unsigned char*)&p3begin[0], (p3end - p3begin) * sizeof(p3begin[0])); | ||
| 388 | SHA256_Final((unsigned char*)&hash1, &ctx); | ||
| 389 | uint256 hash2; | ||
| 390 | SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); | ||
| 391 | return hash2; | ||
| 392 | } | ||
| 393 | |||
| 394 | template<typename T> | ||
| 395 | uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=VERSION) | ||
| 396 | { | ||
| 397 | // Most of the time is spent allocating and deallocating CDataStream's | ||
| 398 | // buffer. If this ever needs to be optimized further, make a CStaticStream | ||
| 399 | // class with its buffer on the stack. | ||
| 400 | CDataStream ss(nType, nVersion); | ||
| 401 | ss.reserve(10000); | ||
| 402 | ss << obj; | ||
| 403 | return Hash(ss.begin(), ss.end()); | ||
| 404 | } | ||
| 405 | |||
| 406 | inline uint160 Hash160(const vector<unsigned char>& vch) | ||
| 407 | { | ||
| 408 | uint256 hash1; | ||
| 409 | SHA256(&vch[0], vch.size(), (unsigned char*)&hash1); | ||
| 410 | uint160 hash2; | ||
| 411 | RIPEMD160((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); | ||
| 412 | return hash2; | ||
| 413 | } | ||