upleb.uk

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

summaryrefslogtreecommitdiff
path: root/src/db.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/db.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/db.h')
-rw-r--r--src/db.h420
1 files changed, 420 insertions, 0 deletions
diff --git a/src/db.h b/src/db.h
new file mode 100644
index 0000000..feaa45e
--- /dev/null
+++ b/src/db.h
@@ -0,0 +1,420 @@
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#include <db_cxx.h>
6class CTransaction;
7class CTxIndex;
8class CDiskBlockIndex;
9class CDiskTxPos;
10class COutPoint;
11class CUser;
12class CReview;
13class CAddress;
14class CWalletTx;
15
16extern map<string, string> mapAddressBook;
17extern bool fClient;
18
19
20extern DbEnv dbenv;
21extern void DBFlush(bool fShutdown);
22
23
24
25
26class CDB
27{
28protected:
29 Db* pdb;
30 string strFile;
31 vector<DbTxn*> vTxn;
32
33 explicit CDB(const char* pszFile, const char* pszMode="r+", bool fTxn=false);
34 ~CDB() { Close(); }
35public:
36 void Close();
37private:
38 CDB(const CDB&);
39 void operator=(const CDB&);
40
41protected:
42 template<typename K, typename T>
43 bool Read(const K& key, T& value)
44 {
45 if (!pdb)
46 return false;
47
48 // Key
49 CDataStream ssKey(SER_DISK);
50 ssKey.reserve(1000);
51 ssKey << key;
52 Dbt datKey(&ssKey[0], ssKey.size());
53
54 // Read
55 Dbt datValue;
56 datValue.set_flags(DB_DBT_MALLOC);
57 int ret = pdb->get(GetTxn(), &datKey, &datValue, 0);
58 memset(datKey.get_data(), 0, datKey.get_size());
59 if (datValue.get_data() == NULL)
60 return false;
61
62 // Unserialize value
63 CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK);
64 ssValue >> value;
65
66 // Clear and free memory
67 memset(datValue.get_data(), 0, datValue.get_size());
68 free(datValue.get_data());
69 return (ret == 0);
70 }
71
72 template<typename K, typename T>
73 bool Write(const K& key, const T& value, bool fOverwrite=true)
74 {
75 if (!pdb)
76 return false;
77
78 // Key
79 CDataStream ssKey(SER_DISK);
80 ssKey.reserve(1000);
81 ssKey << key;
82 Dbt datKey(&ssKey[0], ssKey.size());
83
84 // Value
85 CDataStream ssValue(SER_DISK);
86 ssValue.reserve(10000);
87 ssValue << value;
88 Dbt datValue(&ssValue[0], ssValue.size());
89
90 // Write
91 int ret = pdb->put(GetTxn(), &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE));
92
93 // Clear memory in case it was a private key
94 memset(datKey.get_data(), 0, datKey.get_size());
95 memset(datValue.get_data(), 0, datValue.get_size());
96 return (ret == 0);
97 }
98
99 template<typename K>
100 bool Erase(const K& key)
101 {
102 if (!pdb)
103 return false;
104
105 // Key
106 CDataStream ssKey(SER_DISK);
107 ssKey.reserve(1000);
108 ssKey << key;
109 Dbt datKey(&ssKey[0], ssKey.size());
110
111 // Erase
112 int ret = pdb->del(GetTxn(), &datKey, 0);
113
114 // Clear memory
115 memset(datKey.get_data(), 0, datKey.get_size());
116 return (ret == 0 || ret == DB_NOTFOUND);
117 }
118
119 template<typename K>
120 bool Exists(const K& key)
121 {
122 if (!pdb)
123 return false;
124
125 // Key
126 CDataStream ssKey(SER_DISK);
127 ssKey.reserve(1000);
128 ssKey << key;
129 Dbt datKey(&ssKey[0], ssKey.size());
130
131 // Exists
132 int ret = pdb->exists(GetTxn(), &datKey, 0);
133
134 // Clear memory
135 memset(datKey.get_data(), 0, datKey.get_size());
136 return (ret == 0);
137 }
138
139 Dbc* GetCursor()
140 {
141 if (!pdb)
142 return NULL;
143 Dbc* pcursor = NULL;
144 int ret = pdb->cursor(NULL, &pcursor, 0);
145 if (ret != 0)
146 return NULL;
147 return pcursor;
148 }
149
150 int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags=DB_NEXT)
151 {
152 // Read at cursor
153 Dbt datKey;
154 if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
155 {
156 datKey.set_data(&ssKey[0]);
157 datKey.set_size(ssKey.size());
158 }
159 Dbt datValue;
160 if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
161 {
162 datValue.set_data(&ssValue[0]);
163 datValue.set_size(ssValue.size());
164 }
165 datKey.set_flags(DB_DBT_MALLOC);
166 datValue.set_flags(DB_DBT_MALLOC);
167 int ret = pcursor->get(&datKey, &datValue, fFlags);
168 if (ret != 0)
169 return ret;
170 else if (datKey.get_data() == NULL || datValue.get_data() == NULL)
171 return 99999;
172
173 // Convert to streams
174 ssKey.SetType(SER_DISK);
175 ssKey.clear();
176 ssKey.write((char*)datKey.get_data(), datKey.get_size());
177 ssValue.SetType(SER_DISK);
178 ssValue.clear();
179 ssValue.write((char*)datValue.get_data(), datValue.get_size());
180
181 // Clear and free memory
182 memset(datKey.get_data(), 0, datKey.get_size());
183 memset(datValue.get_data(), 0, datValue.get_size());
184 free(datKey.get_data());
185 free(datValue.get_data());
186 return 0;
187 }
188
189 DbTxn* GetTxn()
190 {
191 if (!vTxn.empty())
192 return vTxn.back();
193 else
194 return NULL;
195 }
196
197public:
198 bool TxnBegin()
199 {
200 if (!pdb)
201 return false;
202 DbTxn* ptxn = NULL;
203 int ret = dbenv.txn_begin(GetTxn(), &ptxn, 0);
204 if (!ptxn || ret != 0)
205 return false;
206 vTxn.push_back(ptxn);
207 return true;
208 }
209
210 bool TxnCommit()
211 {
212 if (!pdb)
213 return false;
214 if (vTxn.empty())
215 return false;
216 int ret = vTxn.back()->commit(0);
217 vTxn.pop_back();
218 return (ret == 0);
219 }
220
221 bool TxnAbort()
222 {
223 if (!pdb)
224 return false;
225 if (vTxn.empty())
226 return false;
227 int ret = vTxn.back()->abort();
228 vTxn.pop_back();
229 return (ret == 0);
230 }
231
232 bool ReadVersion(int& nVersion)
233 {
234 nVersion = 0;
235 return Read(string("version"), nVersion);
236 }
237
238 bool WriteVersion(int nVersion)
239 {
240 return Write(string("version"), nVersion);
241 }
242};
243
244
245
246
247
248
249
250
251class CTxDB : public CDB
252{
253public:
254 CTxDB(const char* pszMode="r+", bool fTxn=false) : CDB(!fClient ? "blkindex.dat" : NULL, pszMode, fTxn) { }
255private:
256 CTxDB(const CTxDB&);
257 void operator=(const CTxDB&);
258public:
259 bool ReadTxIndex(uint256 hash, CTxIndex& txindex);
260 bool UpdateTxIndex(uint256 hash, const CTxIndex& txindex);
261 bool AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight);
262 bool EraseTxIndex(const CTransaction& tx);
263 bool ContainsTx(uint256 hash);
264 bool ReadOwnerTxes(uint160 hash160, int nHeight, vector<CTransaction>& vtx);
265 bool ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex);
266 bool ReadDiskTx(uint256 hash, CTransaction& tx);
267 bool ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex);
268 bool ReadDiskTx(COutPoint outpoint, CTransaction& tx);
269 bool WriteBlockIndex(const CDiskBlockIndex& blockindex);
270 bool EraseBlockIndex(uint256 hash);
271 bool ReadHashBestChain(uint256& hashBestChain);
272 bool WriteHashBestChain(uint256 hashBestChain);
273 bool LoadBlockIndex();
274};
275
276
277
278
279
280class CReviewDB : public CDB
281{
282public:
283 CReviewDB(const char* pszMode="r+", bool fTxn=false) : CDB("reviews.dat", pszMode, fTxn) { }
284private:
285 CReviewDB(const CReviewDB&);
286 void operator=(const CReviewDB&);
287public:
288 bool ReadUser(uint256 hash, CUser& user)
289 {
290 return Read(make_pair(string("user"), hash), user);
291 }
292
293 bool WriteUser(uint256 hash, const CUser& user)
294 {
295 return Write(make_pair(string("user"), hash), user);
296 }
297
298 bool ReadReviews(uint256 hash, vector<CReview>& vReviews);
299 bool WriteReviews(uint256 hash, const vector<CReview>& vReviews);
300};
301
302
303
304
305
306class CMarketDB : public CDB
307{
308public:
309 CMarketDB(const char* pszMode="r+", bool fTxn=false) : CDB("market.dat", pszMode, fTxn) { }
310private:
311 CMarketDB(const CMarketDB&);
312 void operator=(const CMarketDB&);
313};
314
315
316
317
318
319class CAddrDB : public CDB
320{
321public:
322 CAddrDB(const char* pszMode="r+", bool fTxn=false) : CDB("addr.dat", pszMode, fTxn) { }
323private:
324 CAddrDB(const CAddrDB&);
325 void operator=(const CAddrDB&);
326public:
327 bool WriteAddress(const CAddress& addr);
328 bool LoadAddresses();
329};
330
331bool LoadAddresses();
332
333
334
335
336
337class CWalletDB : public CDB
338{
339public:
340 CWalletDB(const char* pszMode="r+", bool fTxn=false) : CDB("wallet.dat", pszMode, fTxn) { }
341private:
342 CWalletDB(const CWalletDB&);
343 void operator=(const CWalletDB&);
344public:
345 bool ReadName(const string& strAddress, string& strName)
346 {
347 strName = "";
348 return Read(make_pair(string("name"), strAddress), strName);
349 }
350
351 bool WriteName(const string& strAddress, const string& strName)
352 {
353 mapAddressBook[strAddress] = strName;
354 return Write(make_pair(string("name"), strAddress), strName);
355 }
356
357 bool EraseName(const string& strAddress)
358 {
359 mapAddressBook.erase(strAddress);
360 return Erase(make_pair(string("name"), strAddress));
361 }
362
363 bool ReadTx(uint256 hash, CWalletTx& wtx)
364 {
365 return Read(make_pair(string("tx"), hash), wtx);
366 }
367
368 bool WriteTx(uint256 hash, const CWalletTx& wtx)
369 {
370 return Write(make_pair(string("tx"), hash), wtx);
371 }
372
373 bool EraseTx(uint256 hash)
374 {
375 return Erase(make_pair(string("tx"), hash));
376 }
377
378 bool ReadKey(const vector<unsigned char>& vchPubKey, CPrivKey& vchPrivKey)
379 {
380 vchPrivKey.clear();
381 return Read(make_pair(string("key"), vchPubKey), vchPrivKey);
382 }
383
384 bool WriteKey(const vector<unsigned char>& vchPubKey, const CPrivKey& vchPrivKey)
385 {
386 return Write(make_pair(string("key"), vchPubKey), vchPrivKey, false);
387 }
388
389 bool ReadDefaultKey(vector<unsigned char>& vchPubKey)
390 {
391 vchPubKey.clear();
392 return Read(string("defaultkey"), vchPubKey);
393 }
394
395 bool WriteDefaultKey(const vector<unsigned char>& vchPubKey)
396 {
397 return Write(string("defaultkey"), vchPubKey);
398 }
399
400 template<typename T>
401 bool ReadSetting(const string& strKey, T& value)
402 {
403 return Read(make_pair(string("setting"), strKey), value);
404 }
405
406 template<typename T>
407 bool WriteSetting(const string& strKey, const T& value)
408 {
409 return Write(make_pair(string("setting"), strKey), value);
410 }
411
412 bool LoadWallet(vector<unsigned char>& vchDefaultKeyRet);
413};
414
415bool LoadWallet();
416
417inline bool SetAddressBookName(const string& strAddress, const string& strName)
418{
419 return CWalletDB().WriteName(strAddress, strName);
420}