Bitcoin ABC 0.26.3
P2P Digital Currency
Loading...
Searching...
No Matches
txdb.cpp
Go to the documentation of this file.
1// Copyright (c) 2009-2010 Satoshi Nakamoto
2// Copyright (c) 2009-2018 The Bitcoin Core developers
3// Distributed under the MIT software license, see the accompanying
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6#include <txdb.h>
7
8#include <chain.h>
9#include <common/system.h>
10#include <logging.h>
11#include <node/ui_interface.h>
12#include <pow/pow.h>
13#include <random.h>
14#include <shutdown.h>
15#include <util/translation.h>
16#include <util/vector.h>
17#include <version.h>
18
19#include <cstdint>
20#include <memory>
21
22static constexpr uint8_t DB_COIN{'C'};
23static constexpr uint8_t DB_COINS{'c'};
24static constexpr uint8_t DB_BLOCK_FILES{'f'};
25static constexpr uint8_t DB_BLOCK_INDEX{'b'};
26
27static constexpr uint8_t DB_BEST_BLOCK{'B'};
28static constexpr uint8_t DB_HEAD_BLOCKS{'H'};
29static constexpr uint8_t DB_FLAG{'F'};
30static constexpr uint8_t DB_REINDEX_FLAG{'R'};
31static constexpr uint8_t DB_LAST_BLOCK{'l'};
32
33// Keys used in previous version that might still be found in the DB:
34static constexpr uint8_t DB_TXINDEX_BLOCK{'T'};
35// uint8_t DB_TXINDEX{'t'}
36
39 if (block_tree_db.Read(DB_TXINDEX_BLOCK, ignored)) {
40 return util::Error{
41 _("The -txindex upgrade started by a previous version can not "
42 "be completed. Restart with the previous version or run a "
43 "full -reindex.")};
44 }
45 bool txindex_legacy_flag{false};
46 block_tree_db.ReadFlag("txindex", txindex_legacy_flag);
48 // Disable legacy txindex and warn once about occupied disk space
49 if (!block_tree_db.WriteFlag("txindex", false)) {
51 "Failed to write block index db flag 'txindex'='0'")};
52 }
53 return util::Error{
54 _("The block index db contains a legacy 'txindex'. To clear the "
55 "occupied disk space, run a full -reindex, otherwise ignore "
56 "this error. This error message will not be displayed again.")};
57 }
58 return {};
59}
60
61namespace {
62
63struct CoinEntry {
64 COutPoint *outpoint;
65 uint8_t key;
66 explicit CoinEntry(const COutPoint *ptr)
67 : outpoint(const_cast<COutPoint *>(ptr)), key(DB_COIN) {}
68
69 SERIALIZE_METHODS(CoinEntry, obj) {
70 TxId id = obj.outpoint->GetTxId();
71 uint32_t n = obj.outpoint->GetN();
72 READWRITE(obj.key, id, VARINT(n));
73 SER_READ(obj, *obj.outpoint = COutPoint(id, n));
74 }
75};
76} // namespace
77
79 : m_db_params{std::move(db_params)}, m_options{std::move(options)},
80 m_db{std::make_unique<CDBWrapper>(m_db_params)} {}
81
83 // We can't do this operation with an in-memory DB since we'll lose all the
84 // coins upon reset.
86 // Have to do a reset first to get the original `m_db` state to release
87 // its filesystem lock.
88 m_db.reset();
90 m_db_params.wipe_data = false;
91 m_db = std::make_unique<CDBWrapper>(m_db_params);
92 }
93}
94
95bool CCoinsViewDB::GetCoin(const COutPoint &outpoint, Coin &coin) const {
96 return m_db->Read(CoinEntry(&outpoint), coin);
97}
98
99bool CCoinsViewDB::HaveCoin(const COutPoint &outpoint) const {
100 return m_db->Exists(CoinEntry(&outpoint));
101}
102
105 if (!m_db->Read(DB_BEST_BLOCK, hashBestChain)) {
106 return BlockHash();
107 }
108 return hashBestChain;
109}
110
111std::vector<BlockHash> CCoinsViewDB::GetHeadBlocks() const {
112 std::vector<BlockHash> vhashHeadBlocks;
113 if (!m_db->Read(DB_HEAD_BLOCKS, vhashHeadBlocks)) {
114 return std::vector<BlockHash>();
115 }
116 return vhashHeadBlocks;
117}
118
120 bool erase) {
121 CDBBatch batch(*m_db);
122 size_t count = 0;
123 size_t changed = 0;
124 assert(!hashBlock.IsNull());
125
127 if (old_tip.IsNull()) {
128 // We may be in the middle of replaying.
129 std::vector<BlockHash> old_heads = GetHeadBlocks();
130 if (old_heads.size() == 2) {
131 assert(old_heads[0] == hashBlock);
132 old_tip = old_heads[1];
133 }
134 }
135
136 // In the first batch, mark the database as being in the middle of a
137 // transition from old_tip to hashBlock.
138 // A vector is used for future extensibility, as we may want to support
139 // interrupting after partial writes from multiple independent reorgs.
140 batch.Erase(DB_BEST_BLOCK);
141 batch.Write(DB_HEAD_BLOCKS, Vector(hashBlock, old_tip));
142
143 for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) {
144 if (it->second.flags & CCoinsCacheEntry::DIRTY) {
145 CoinEntry entry(&it->first);
146 if (it->second.coin.IsSpent()) {
147 batch.Erase(entry);
148 } else {
149 batch.Write(entry, it->second.coin);
150 }
151 changed++;
152 }
153 count++;
154 it = erase ? mapCoins.erase(it) : std::next(it);
156 LogPrint(BCLog::COINDB, "Writing partial batch of %.2f MiB\n",
157 batch.SizeEstimate() * (1.0 / 1048576.0));
158 m_db->WriteBatch(batch);
159 batch.Clear();
161 static FastRandomContext rng;
163 LogPrintf("Simulating a crash. Goodbye.\n");
164 _Exit(0);
165 }
166 }
167 }
168 }
169
170 // In the last batch, mark the database as consistent with hashBlock again.
171 batch.Erase(DB_HEAD_BLOCKS);
172 batch.Write(DB_BEST_BLOCK, hashBlock);
173
174 LogPrint(BCLog::COINDB, "Writing final batch of %.2f MiB\n",
175 batch.SizeEstimate() * (1.0 / 1048576.0));
176 bool ret = m_db->WriteBatch(batch);
178 "Committed %u changed transaction outputs (out of "
179 "%u) to coin database...\n",
180 (unsigned int)changed, (unsigned int)count);
181 return ret;
182}
183
185 return m_db->EstimateSize(DB_COIN, uint8_t(DB_COIN + 1));
186}
187
189 return Read(std::make_pair(DB_BLOCK_FILES, nFile), info);
190}
191
193 if (fReindexing) {
194 return Write(DB_REINDEX_FLAG, uint8_t{'1'});
195 } else {
196 return Erase(DB_REINDEX_FLAG);
197 }
198}
199
201 return Exists(DB_REINDEX_FLAG);
202}
203
205 return Read(DB_LAST_BLOCK, nFile);
206}
207
210 const_cast<CDBWrapper &>(*m_db).NewIterator(), GetBestBlock());
216 i->pcursor->Seek(DB_COIN);
217 // Cache key of first record
218 if (i->pcursor->Valid()) {
219 CoinEntry entry(&i->keyTmp.second);
220 i->pcursor->GetKey(entry);
221 i->keyTmp.first = entry.key;
222 } else {
223 // Make sure Valid() and GetKey() return false
224 i->keyTmp.first = 0;
225 }
226 return i;
227}
228
229bool CCoinsViewDBCursor::GetKey(COutPoint &key) const {
230 // Return cached key
231 if (keyTmp.first == DB_COIN) {
232 key = keyTmp.second;
233 return true;
234 }
235 return false;
236}
237
239 return pcursor->GetValue(coin);
240}
241
243 return pcursor->GetValueSize();
244}
245
247 return keyTmp.first == DB_COIN;
248}
249
251 pcursor->Next();
252 CoinEntry entry(&keyTmp.second);
253 if (!pcursor->Valid() || !pcursor->GetKey(entry)) {
254 // Invalidate cached key after last record so that Valid() and GetKey()
255 // return false
256 keyTmp.first = 0;
257 } else {
258 keyTmp.first = entry.key;
259 }
260}
261
263 const std::vector<std::pair<int, const CBlockFileInfo *>> &fileInfo,
264 int nLastFile, const std::vector<const CBlockIndex *> &blockinfo) {
265 CDBBatch batch(*this);
266 for (std::vector<std::pair<int, const CBlockFileInfo *>>::const_iterator
267 it = fileInfo.begin();
268 it != fileInfo.end(); it++) {
269 batch.Write(std::make_pair(DB_BLOCK_FILES, it->first), *it->second);
270 }
272 for (std::vector<const CBlockIndex *>::const_iterator it =
273 blockinfo.begin();
274 it != blockinfo.end(); it++) {
275 batch.Write(std::make_pair(DB_BLOCK_INDEX, (*it)->GetBlockHash()),
276 CDiskBlockIndex(*it));
277 }
278 return WriteBatch(batch, true);
279}
280
281bool CBlockTreeDB::WriteFlag(const std::string &name, bool fValue) {
282 return Write(std::make_pair(DB_FLAG, name),
283 fValue ? uint8_t{'1'} : uint8_t{'0'});
284}
285
286bool CBlockTreeDB::ReadFlag(const std::string &name, bool &fValue) {
287 uint8_t ch;
288 if (!Read(std::make_pair(DB_FLAG, name), ch)) {
289 return false;
290 }
291 fValue = ch == uint8_t{'1'};
292 return true;
293}
294
296 const Consensus::Params &params,
297 std::function<CBlockIndex *(const BlockHash &)> insertBlockIndex) {
299 std::unique_ptr<CDBIterator> pcursor(NewIterator());
300
301 uint64_t version = 0;
302 pcursor->Seek("version");
303 if (pcursor->Valid()) {
304 pcursor->GetValue(version);
305 }
306
307 if (version != CLIENT_VERSION) {
308 return error("%s: Invalid block index database version: %s", __func__,
309 version);
310 }
311
312 pcursor->Seek(std::make_pair(DB_BLOCK_INDEX, uint256()));
313
314 // Load m_block_index
315 while (pcursor->Valid()) {
316 if (ShutdownRequested()) {
317 return false;
318 }
319 std::pair<uint8_t, uint256> key;
320 if (!pcursor->GetKey(key) || key.first != DB_BLOCK_INDEX) {
321 break;
322 }
323
325 if (!pcursor->GetValue(diskindex)) {
326 return error("%s : failed to read value", __func__);
327 }
328
329 // Construct block index object
331 insertBlockIndex(diskindex.ConstructBlockHash());
332 pindexNew->pprev = insertBlockIndex(diskindex.hashPrev);
333 pindexNew->nHeight = diskindex.nHeight;
334 pindexNew->nFile = diskindex.nFile;
335 pindexNew->nDataPos = diskindex.nDataPos;
336 pindexNew->nUndoPos = diskindex.nUndoPos;
337 pindexNew->nVersion = diskindex.nVersion;
338 pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot;
339 pindexNew->nTime = diskindex.nTime;
340 pindexNew->nBits = diskindex.nBits;
341 pindexNew->nNonce = diskindex.nNonce;
342 pindexNew->nStatus = diskindex.nStatus;
343 pindexNew->nTx = diskindex.nTx;
344
345 if (!CheckProofOfWork(pindexNew->GetBlockHash(), pindexNew->nBits,
346 params)) {
347 return error("%s: CheckProofOfWork failed: %s", __func__,
348 pindexNew->ToString());
349 }
350
351 pcursor->Next();
352 }
353
354 return true;
355}
356
357namespace {
359class CCoins {
360public:
362 bool fCoinBase;
363
366 std::vector<CTxOut> vout;
367
369 int nHeight;
370
372 CCoins() : fCoinBase(false), vout(0), nHeight(0) {}
373
374 template <typename Stream> void Unserialize(Stream &s) {
375 uint32_t nCode = 0;
376 // version
377 unsigned int nVersionDummy = 0;
379 // header code
381 fCoinBase = nCode & 1;
382 std::vector<bool> vAvail(2, false);
383 vAvail[0] = (nCode & 2) != 0;
384 vAvail[1] = (nCode & 4) != 0;
385 uint32_t nMaskCode = (nCode / 8) + ((nCode & 6) != 0 ? 0 : 1);
386 // spentness bitmask
387 while (nMaskCode > 0) {
388 uint8_t chAvail = 0;
390 for (unsigned int p = 0; p < 8; p++) {
391 bool f = (chAvail & (1 << p)) != 0;
392 vAvail.push_back(f);
393 }
394 if (chAvail != 0) {
395 nMaskCode--;
396 }
397 }
398 // txouts themself
399 vout.assign(vAvail.size(), CTxOut());
400 for (size_t i = 0; i < vAvail.size(); i++) {
401 if (vAvail[i]) {
403 }
404 }
405 // coinbase height
407 }
408};
409} // namespace
410
417 std::unique_ptr<CDBIterator> pcursor(m_db->NewIterator());
418 pcursor->Seek(std::make_pair(DB_COINS, uint256()));
419 if (!pcursor->Valid()) {
420 return true;
421 }
422
423 int64_t count = 0;
424 LogPrintf("Upgrading utxo-set database...\n");
425 size_t batch_size = 1 << 24;
426 CDBBatch batch(*m_db);
427 int reportDone = -1;
428 std::pair<uint8_t, uint256> key;
429 std::pair<uint8_t, uint256> prev_key = {DB_COINS, uint256()};
430 while (pcursor->Valid()) {
431 if (ShutdownRequested()) {
432 break;
433 }
434
435 if (!pcursor->GetKey(key) || key.first != DB_COINS) {
436 break;
437 }
438
439 if (count++ % 256 == 0) {
440 uint32_t high =
441 0x100 * *key.second.begin() + *(key.second.begin() + 1);
442 int percentageDone = (int)(high * 100.0 / 65536.0 + 0.5);
443 uiInterface.ShowProgress(_("Upgrading UTXO database").translated,
444 percentageDone, true);
445 if (reportDone < percentageDone / 10) {
446 // report max. every 10% step
449 }
450 }
451
452 CCoins old_coins;
453 if (!pcursor->GetValue(old_coins)) {
454 return error("%s: cannot parse CCoins record", __func__);
455 }
456
457 const TxId id(key.second);
458 for (size_t i = 0; i < old_coins.vout.size(); ++i) {
459 if (!old_coins.vout[i].IsNull() &&
460 !old_coins.vout[i].scriptPubKey.IsUnspendable()) {
461 Coin newcoin(std::move(old_coins.vout[i]), old_coins.nHeight,
462 old_coins.fCoinBase);
463 COutPoint outpoint(id, i);
464 CoinEntry entry(&outpoint);
465 batch.Write(entry, newcoin);
466 }
467 }
468
469 batch.Erase(key);
470 if (batch.SizeEstimate() > batch_size) {
471 m_db->WriteBatch(batch);
472 batch.Clear();
473 m_db->CompactRange(prev_key, key);
474 prev_key = key;
475 }
476
477 pcursor->Next();
478 }
479
480 m_db->WriteBatch(batch);
481 m_db->CompactRange({DB_COINS, uint256()}, key);
482 uiInterface.ShowProgress("", 100, false);
483 LogPrintf("[%s].\n", ShutdownRequested() ? "CANCELLED" : "DONE");
484 return !ShutdownRequested();
485}
486
488 // This method used to add the block size to pre-0.22.8 block index
489 // databases. This is no longer supported as of 0.25.5, but the method is
490 // kept to update the version number in the database.
491 std::unique_ptr<CDBIterator> pcursor(NewIterator());
492
493 uint64_t version = 0;
494 pcursor->Seek("version");
495 if (pcursor->Valid()) {
496 pcursor->GetValue(version);
497 }
498
499 if (version >= CLIENT_VERSION) {
500 // The DB is already up to date.
501 return true;
502 }
503
504 pcursor->Seek(std::make_pair(DB_BLOCK_INDEX, uint256()));
505
506 // The DB is not empty, and the version is either non-existent or too old.
507 // The node requires a reindex.
508 if (pcursor->Valid() && version < CDiskBlockIndex::TRACK_SIZE_VERSION) {
509 LogPrintf(
510 "\nThe database is too old. The block index cannot be upgraded "
511 "and reindexing is required.\n");
512 return false;
513 }
514
515 // The DB is empty or recent enough.
516 // Just write the new version number and consider the upgrade done.
517 CDBBatch batch(*this);
518 LogPrintf("Updating the block index database version to %d\n",
520 batch.Write("version", uint64_t(CLIENT_VERSION));
521 return WriteBatch(batch);
522}
constexpr uint8_t DB_BEST_BLOCK
Definition base.cpp:23
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition blockindex.h:25
Access to the block database (blocks/index/)
Definition txdb.h:117
bool ReadBlockFileInfo(int nFile, CBlockFileInfo &info)
Definition txdb.cpp:188
bool Upgrade()
Attempt to update from an older database format.
Definition txdb.cpp:487
bool WriteReindexing(bool fReindexing)
Definition txdb.cpp:192
bool IsReindexing() const
Definition txdb.cpp:200
bool WriteBatchSync(const std::vector< std::pair< int, const CBlockFileInfo * > > &fileInfo, int nLastFile, const std::vector< const CBlockIndex * > &blockinfo)
Definition txdb.cpp:262
bool ReadFlag(const std::string &name, bool &fValue)
Definition txdb.cpp:286
bool ReadLastBlockFile(int &nFile)
Definition txdb.cpp:204
bool LoadBlockIndexGuts(const Consensus::Params &params, std::function< CBlockIndex *(const BlockHash &)> insertBlockIndex) EXCLUSIVE_LOCKS_REQUIRED(
Definition txdb.h:129
bool WriteFlag(const std::string &name, bool fValue)
Definition txdb.cpp:281
Cursor for iterating over CoinsView state.
Definition coins.h:143
Specialization of CCoinsViewCursor to iterate over a CCoinsViewDB.
Definition txdb.h:96
std::unique_ptr< CDBIterator > pcursor
Definition txdb.h:110
bool GetKey(COutPoint &key) const override
Definition txdb.cpp:229
bool GetValue(Coin &coin) const override
Definition txdb.cpp:238
bool Valid() const override
Definition txdb.cpp:246
unsigned int GetValueSize() const override
Definition txdb.cpp:242
void Next() override
Definition txdb.cpp:250
std::pair< char, COutPoint > keyTmp
Definition txdb.h:111
BlockHash GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
Definition txdb.cpp:103
std::vector< BlockHash > GetHeadBlocks() const override
Retrieve the range of blocks that may have been only partially written.
Definition txdb.cpp:111
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition txdb.cpp:95
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.
Definition txdb.cpp:99
std::unique_ptr< CDBWrapper > m_db
Definition txdb.h:69
bool Upgrade()
Attempt to update from an older database format.
Definition txdb.cpp:416
CCoinsViewCursor * Cursor() const override
Get a cursor to iterate over the whole state.
Definition txdb.cpp:208
CCoinsViewDB(DBParams db_params, CoinsViewOptions options)
Definition txdb.cpp:78
bool BatchWrite(CCoinsMap &mapCoins, const BlockHash &hashBlock, bool erase=true) override
Do a bulk modification (multiple Coin changes + BestBlock change).
Definition txdb.cpp:119
void ResizeCache(size_t new_cache_size) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Dynamically alter the underlying leveldb cache size.
Definition txdb.cpp:82
CoinsViewOptions m_options
Definition txdb.h:68
size_t EstimateSize() const override
Estimate database size (0 if not implemented)
Definition txdb.cpp:184
DBParams m_db_params
Definition txdb.h:67
Batch of changes queued to be written to a CDBWrapper.
Definition dbwrapper.h:78
void Erase(const K &key)
Definition dbwrapper.h:127
size_t SizeEstimate() const
Definition dbwrapper.h:142
void Write(const K &key, const V &value)
Definition dbwrapper.h:103
void Clear()
Definition dbwrapper.h:98
bool WriteBatch(CDBBatch &batch, bool fSync=false)
bool Read(const K &key, V &value) const
Definition dbwrapper.h:254
CDBIterator * NewIterator()
Definition dbwrapper.h:320
bool Erase(const K &key, bool fSync=false)
Definition dbwrapper.h:309
bool Write(const K &key, const V &value, bool fSync=false)
Definition dbwrapper.h:279
bool Exists(const K &key) const
Definition dbwrapper.h:293
Used to marshal pointers into hashes for db storage.
Definition chain.h:69
static constexpr int TRACK_SIZE_VERSION
Definition chain.h:71
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition transaction.h:20
An output of a transaction.
A UTXO entry.
Definition coins.h:28
Fast randomness source.
Definition random.h:156
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
Definition random.h:231
uint8_t * begin()
Definition uint256.h:85
bool IsNull() const
Definition uint256.h:32
256-bit opaque blob.
Definition uint256.h:129
static constexpr int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
std::unordered_map< COutPoint, CCoinsCacheEntry, SaltedOutpointHasher, std::equal_to< COutPoint >, PoolAllocator< std::pair< const COutPoint, CCoinsCacheEntry >, sizeof(std::pair< const COutPoint, CCoinsCacheEntry >)+sizeof(void *) *4 > > CCoinsMap
PoolAllocator's MAX_BLOCK_SIZE_BYTES parameter here uses sizeof the data, and adds the size of 4 poin...
Definition coins.h:138
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
Definition cs_main.cpp:7
bool error(const char *fmt, const Args &...args)
Definition logging.h:226
#define LogPrint(category,...)
Definition logging.h:211
#define LogPrintfToBeContinued
These are aliases used to explicitly state that the message should not end with a newline character.
Definition logging.h:223
#define LogPrintf(...)
Definition logging.h:207
unsigned int nHeight
@ COINDB
Definition logging.h:58
Implement std::hash so RCUPtr can be used as a key for maps or sets.
Definition rcu.h:259
bool CheckProofOfWork(const BlockHash &hash, uint32_t nBits, const Consensus::Params &params)
Check whether a block hash satisfies the proof-of-work requirement specified by nBits.
Definition pow.cpp:87
T GetRand(T nMax=std::numeric_limits< T >::max()) noexcept
Generate a uniform random integer of type T in the range [0..nMax) nMax defaults to std::numeric_limi...
Definition random.h:85
const char * name
Definition rest.cpp:47
#define VARINT(obj)
Definition serialize.h:579
#define VARINT_MODE(obj, mode)
Definition serialize.h:578
@ NONNEGATIVE_SIGNED
#define SERIALIZE_METHODS(cls, obj)
Implement the Serialize and Unserialize methods by delegating to a single templated static method tha...
Definition serialize.h:213
void Unserialize(Stream &, char)=delete
#define SER_READ(obj, code)
Definition serialize.h:169
#define READWRITE(...)
Definition serialize.h:166
bool ShutdownRequested()
Returns true if a shutdown is requested, false otherwise.
Definition shutdown.cpp:85
A BlockHash is a unqiue identifier for a block.
Definition blockhash.h:13
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
Definition block.h:105
@ DIRTY
DIRTY means the CCoinsCacheEntry is potentially different from the version in the parent cache.
Definition coins.h:104
User-controlled performance and debug options.
Definition txdb.h:56
int simulate_crash_ratio
If non-zero, randomly exit when the database is flushed with (1/ratio) probability.
Definition txdb.h:61
size_t batch_write_bytes
Maximum database write batch size in bytes.
Definition txdb.h:58
Parameters that influence chain consensus.
Definition params.h:34
Application-specific storage settings.
Definition dbwrapper.h:32
bool wipe_data
If true, remove all existing data.
Definition dbwrapper.h:40
size_t cache_bytes
Configures various leveldb cache settings.
Definition dbwrapper.h:36
bool memory_only
If true, use leveldb's memory environment.
Definition dbwrapper.h:38
A TxId is the identifier of a transaction.
Definition txid.h:14
std::string translated
Definition translation.h:19
#define AssertLockHeld(cs)
Definition sync.h:146
static int count
Definition tests.c:31
bilingual_str _(const char *psz)
Translation function.
Definition translation.h:68
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
Definition translation.h:36
static constexpr uint8_t DB_TXINDEX_BLOCK
Definition txdb.cpp:34
static constexpr uint8_t DB_LAST_BLOCK
Definition txdb.cpp:31
static constexpr uint8_t DB_HEAD_BLOCKS
Definition txdb.cpp:28
static constexpr uint8_t DB_REINDEX_FLAG
Definition txdb.cpp:30
static constexpr uint8_t DB_BEST_BLOCK
Definition txdb.cpp:27
util::Result< void > CheckLegacyTxindex(CBlockTreeDB &block_tree_db)
Definition txdb.cpp:37
static constexpr uint8_t DB_COIN
Definition txdb.cpp:22
static constexpr uint8_t DB_FLAG
Definition txdb.cpp:29
static constexpr uint8_t DB_COINS
Definition txdb.cpp:23
static constexpr uint8_t DB_BLOCK_FILES
Definition txdb.cpp:24
static constexpr uint8_t DB_BLOCK_INDEX
Definition txdb.cpp:25
CClientUIInterface uiInterface
assert(!tx.IsCoinBase())
std::vector< typename std::common_type< Args... >::type > Vector(Args &&...args)
Construct a vector with the specified elements.
Definition vector.h:21