upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/util.h
diff options
context:
space:
mode:
authorBitflash-sh <btf01@proton.me>2026-07-24 11:18:11 -0300
committerBitflash-sh <btf01@proton.me>2026-07-24 11:18:11 -0300
commit51d617e70f90a972185917ea0096c1ecef2bfa8b (patch)
tree9fbbcd867de9de9d0776afdd02f594ba312c46eb /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.h413
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__)
7typedef __int64 int64;
8typedef unsigned __int64 uint64;
9#else
10typedef long long int64;
11typedef 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
57template<typename T>
58inline T& REF(const T& val)
59{
60 return (T&)val;
61}
62
63
64
65
66
67
68
69
70
71extern bool fDebug;
72
73void RandAddSeed(bool fPerfmon=false);
74int my_snprintf(char* buffer, size_t limit, const char* format, ...);
75string strprintf(const char* format, ...);
76bool error(const char* format, ...);
77void PrintException(std::exception* pex, const char* pszThread);
78void ParseString(const string& str, char c, vector<string>& v);
79string FormatMoney(int64 n, bool fPlus=false);
80bool ParseMoney(const char* pszIn, int64& nRet);
81bool FileExists(const char* psz);
82int GetFilesize(FILE* file);
83uint64 GetRand(uint64 nMax);
84int64 GetTime();
85int64 GetAdjustedTime();
86void 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
101class CCriticalSection
102{
103protected:
104 CRITICAL_SECTION cs;
105public:
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
117class CCriticalBlock
118{
119protected:
120 CRITICAL_SECTION* pcs;
121public:
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
135class CTryCriticalBlock
136{
137protected:
138 CRITICAL_SECTION* pcs;
139public:
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
161inline string i64tostr(int64 n)
162{
163 return strprintf("%" PRId64, n);
164}
165
166inline string itostr(int n)
167{
168 return strprintf("%d", n);
169}
170
171inline 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
180inline 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
189inline int atoi(const string& str)
190{
191 return atoi(str.c_str());
192}
193
194inline int roundint(double d)
195{
196 return (int)(d > 0 ? d + 0.5 : d - 0.5);
197}
198
199template<typename T>
200string 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
210template<typename T>
211string 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
221template<typename T>
222void 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
234inline 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
318inline 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
352template<typename T1>
353inline 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
362template<typename T1, typename T2>
363inline 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
377template<typename T1, typename T2, typename T3>
378inline 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
394template<typename T>
395uint256 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
406inline 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}