41 _(
"The -txindex upgrade started by a previous version can not "
42 "be completed. Restart with the previous version or run a "
45 bool txindex_legacy_flag{
false};
46 block_tree_db.
ReadFlag(
"txindex", txindex_legacy_flag);
47 if (txindex_legacy_flag) {
49 if (!block_tree_db.
WriteFlag(
"txindex",
false)) {
51 "Failed to write block index db flag 'txindex'='0'")};
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.")};
62 std::unique_ptr<CDBIterator> cursor{
m_db->NewIterator()};
65 return cursor->Valid();
73 explicit CoinEntry(
const COutPoint *ptr)
74 : outpoint(const_cast<COutPoint *>(ptr)) {}
77 TxId id = obj.outpoint->GetTxId();
78 uint32_t n = obj.outpoint->GetN();
80 SER_READ(obj, *obj.outpoint = COutPoint(
id, n));
86 : m_db_params{
std::move(db_params)}, m_options{
std::move(options)},
103 return m_db->Read(CoinEntry(&outpoint), coin);
107 return m_db->Exists(CoinEntry(&outpoint));
115 return hashBestChain;
119 std::vector<BlockHash> vhashHeadBlocks;
121 return std::vector<BlockHash>();
123 return vhashHeadBlocks;
137 if (old_heads.size() == 2) {
138 assert(old_heads[0] == hashBlock);
139 old_tip = old_heads[1];
150 for (
auto it{cursor.
Begin()}; it != cursor.
End();) {
151 if (it->second.IsDirty()) {
152 CoinEntry entry(&it->first);
153 if (it->second.coin.IsSpent()) {
156 batch.
Write(entry, it->second.coin);
165 m_db->WriteBatch(batch);
170 LogPrintf(
"Simulating a crash. Goodbye.\n");
183 bool ret =
m_db->WriteBatch(batch);
185 "Committed %u changed transaction outputs (out of "
186 "%u) to coin database...\n",
187 (
unsigned int)changed, (
unsigned int)
count);
226 CoinEntry entry(&i->
keyTmp.second);
228 i->
keyTmp.first = entry.key;
246 return pcursor->GetValue(coin);
250 return pcursor->GetValueSize();
259 CoinEntry entry(&
keyTmp.second);
270 const std::vector<std::pair<int, const CBlockFileInfo *>> &fileInfo,
271 int nLastFile,
const std::vector<const CBlockIndex *> &blockinfo) {
273 for (std::vector<std::pair<int, const CBlockFileInfo *>>::const_iterator
274 it = fileInfo.begin();
275 it != fileInfo.end(); it++) {
279 for (std::vector<const CBlockIndex *>::const_iterator it =
281 it != blockinfo.end(); it++) {
290 fValue ? uint8_t{
'1'} : uint8_t{
'0'});
298 fValue = ch == uint8_t{
'1'};
307 std::unique_ptr<CDBIterator> pcursor(
NewIterator());
309 uint64_t version = 0;
310 pcursor->Seek(
"version");
311 if (pcursor->Valid()) {
312 pcursor->GetValue(version);
316 LogError(
"%s: Invalid block index database version: %s\n", __func__,
324 while (pcursor->Valid()) {
328 std::pair<uint8_t, uint256> key;
334 if (!pcursor->GetValue(diskindex)) {
335 LogError(
"%s : failed to read value\n", __func__);
344 pindexNew->nFile = diskindex.nFile;
345 pindexNew->nDataPos = diskindex.nDataPos;
346 pindexNew->nUndoPos = diskindex.nUndoPos;
352 pindexNew->nStatus = diskindex.nStatus;
353 pindexNew->
nTx = diskindex.
nTx;
357 LogError(
"%s: CheckProofOfWork failed: %s\n", __func__,
372 std::unique_ptr<CDBIterator> pcursor(
NewIterator());
374 uint64_t version = 0;
375 pcursor->Seek(
"version");
376 if (pcursor->Valid()) {
377 pcursor->GetValue(version);
389 constexpr int TRACK_SIZE_VERSION = 220800;
390 if (pcursor->Valid() && version < TRACK_SIZE_VERSION) {
392 "\nThe database is too old. The block index cannot be upgraded "
393 "and reindexing is required.\n");
400 LogPrintf(
"Updating the block index database version to %d\n",
The block chain is a tree shaped structure starting with the genesis block at the root,...
std::string ToString() const
CBlockIndex * pprev
pointer to the index of the predecessor of this block
unsigned int nTx
Number of transactions in this block.
int32_t nVersion
block header
BlockHash GetBlockHash() const
int nHeight
height of the entry in the chain. The genesis block has height 0
Access to the block database (blocks/index/)
bool ReadBlockFileInfo(int nFile, CBlockFileInfo &info)
bool Upgrade()
Attempt to update from an older database format.
bool WriteReindexing(bool fReindexing)
bool IsReindexing() const
bool WriteBatchSync(const std::vector< std::pair< int, const CBlockFileInfo * > > &fileInfo, int nLastFile, const std::vector< const CBlockIndex * > &blockinfo)
bool LoadBlockIndexGuts(const Consensus::Params ¶ms, std::function< CBlockIndex *(const BlockHash &)> insertBlockIndex, const util::SignalInterrupt &interrupt) EXCLUSIVE_LOCKS_REQUIRED(
bool ReadFlag(const std::string &name, bool &fValue)
bool ReadLastBlockFile(int &nFile)
bool WriteFlag(const std::string &name, bool fValue)
Cursor for iterating over CoinsView state.
Specialization of CCoinsViewCursor to iterate over a CCoinsViewDB.
std::unique_ptr< CDBIterator > pcursor
bool GetKey(COutPoint &key) const override
bool GetValue(Coin &coin) const override
bool Valid() const override
unsigned int GetValueSize() const override
std::pair< char, COutPoint > keyTmp
BlockHash GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
std::vector< BlockHash > GetHeadBlocks() const override
Retrieve the range of blocks that may have been only partially written.
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.
std::unique_ptr< CDBWrapper > m_db
CCoinsViewCursor * Cursor() const override
Get a cursor to iterate over the whole state.
CCoinsViewDB(DBParams db_params, CoinsViewOptions options)
bool BatchWrite(CoinsViewCacheCursor &cursor, const BlockHash &hashBlock) override
Do a bulk modification (multiple Coin changes + BestBlock change).
void ResizeCache(size_t new_cache_size) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Dynamically alter the underlying leveldb cache size.
CoinsViewOptions m_options
bool NeedsUpgrade()
Whether an unsupported database format is used.
size_t EstimateSize() const override
Estimate database size (0 if not implemented)
Batch of changes queued to be written to a CDBWrapper.
size_t SizeEstimate() const
void Write(const K &key, const V &value)
bool WriteBatch(CDBBatch &batch, bool fSync=false)
bool Read(const K &key, V &value) const
CDBIterator * NewIterator()
bool Erase(const K &key, bool fSync=false)
bool Write(const K &key, const V &value, bool fSync=false)
bool Exists(const K &key) const
Used to marshal pointers into hashes for db storage.
BlockHash ConstructBlockHash() const
I randrange(I range) noexcept
Generate a random integer in the range [0..range), with range > 0.
Helper class that manages an interrupt flag, and allows a thread or signal to interrupt another threa...
static constexpr int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
#define LogPrint(category,...)
Implement std::hash so RCUPtr can be used as a key for maps or sets.
bool CheckProofOfWork(const BlockHash &hash, uint32_t nBits, const Consensus::Params ¶ms)
Check whether a block hash satisfies the proof-of-work requirement specified by nBits.
#define SERIALIZE_METHODS(cls, obj)
Implement the Serialize and Unserialize methods by delegating to a single templated static method tha...
#define SER_READ(obj, code)
A BlockHash is a unqiue identifier for a block.
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
Cursor for iterating over the linked list of flagged entries in CCoinsViewCache.
CoinsCachePair * NextAndMaybeErase(CoinsCachePair ¤t) noexcept
Return the next entry after current, possibly erasing current.
CoinsCachePair * Begin() const noexcept
CoinsCachePair * End() const noexcept
User-controlled performance and debug options.
int simulate_crash_ratio
If non-zero, randomly exit when the database is flushed with (1/ratio) probability.
size_t batch_write_bytes
Maximum database write batch size in bytes.
Parameters that influence chain consensus.
Application-specific storage settings.
bool wipe_data
If true, remove all existing data.
size_t cache_bytes
Configures various leveldb cache settings.
bool memory_only
If true, use leveldb's memory environment.
A TxId is the identifier of a transaction.
bilingual_str _(const char *psz)
Translation function.
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
static constexpr uint8_t DB_TXINDEX_BLOCK
static constexpr uint8_t DB_LAST_BLOCK
static constexpr uint8_t DB_HEAD_BLOCKS
static constexpr uint8_t DB_REINDEX_FLAG
static constexpr uint8_t DB_BEST_BLOCK
util::Result< void > CheckLegacyTxindex(CBlockTreeDB &block_tree_db)
static constexpr uint8_t DB_COIN
static constexpr uint8_t DB_FLAG
static constexpr uint8_t DB_COINS
static constexpr uint8_t DB_BLOCK_FILES
static constexpr uint8_t DB_BLOCK_INDEX
std::vector< typename std::common_type< Args... >::type > Vector(Args &&...args)
Construct a vector with the specified elements.