9 #include <validation.h>    11 #include <boost/thread.hpp>    25     template <
typename Stream, 
typename Operation>
    56     explicit DB(
size_t n_cache_size, 
bool f_memory = 
false, 
bool f_wipe = 
false);
    63     bool WriteTxs(
const std::vector<std::pair<uint256, CDiskTxPos>>& v_pos);
    76     return Read(std::make_pair(
DB_TXINDEX, txid), pos);
    82     for (
const auto& tuple : v_pos) {
    85     return WriteBatch(batch);
    94                                          const std::pair<unsigned char, uint256>& begin_key,
    95                                          const std::pair<unsigned char, uint256>& end_key)
   122     bool f_legacy_flag = 
false;
   123     block_tree_db.
ReadFlag(
"txindex", f_legacy_flag);
   126             return error(
"%s: cannot write block indicator", __func__);
   128         if (!block_tree_db.
WriteFlag(
"txindex", 
false)) {
   129             return error(
"%s: cannot write block index db flag", __func__);
   139     LogPrintf(
"Upgrading txindex database... [0%%]\n");
   140     uiInterface.ShowProgress(
_(
"Upgrading txindex database"), 0, 
true);
   142     const size_t batch_size = 1 << 24; 
   145     CDBBatch batch_olddb(block_tree_db);
   147     std::pair<unsigned char, uint256> key;
   149     std::pair<unsigned char, uint256> prev_key = begin_key;
   151     bool interrupted = 
false;
   152     std::unique_ptr<CDBIterator> cursor(block_tree_db.
NewIterator());
   153     for (cursor->Seek(begin_key); cursor->Valid(); cursor->Next()) {
   154         boost::this_thread::interruption_point();
   160         if (!cursor->GetKey(key)) {
   161             return error(
"%s: cannot get key from valid cursor", __func__);
   168         if (++count % 256 == 0) {
   171             const uint256& txid = key.second;
   172             uint32_t high_nibble =
   173                 (
static_cast<uint32_t
>(*(txid.
begin() + 0)) << 8) +
   174                 (static_cast<uint32_t>(*(txid.
begin() + 1)) << 0);
   175             int percentage_done = (int)(high_nibble * 100.0 / 65536.0 + 0.5);
   177             uiInterface.ShowProgress(
_(
"Upgrading txindex database"), percentage_done, 
true);
   178             if (report_done < percentage_done/10) {
   179                 LogPrintf(
"Upgrading txindex database... [%d%%]\n", percentage_done);
   180                 report_done = percentage_done/10;
   185         if (!cursor->GetValue(value)) {
   186             return error(
"%s: cannot parse txindex record", __func__);
   188         batch_newdb.
Write(key, value);
   189         batch_olddb.
Erase(key);
   195             WriteTxIndexMigrationBatches(*
this, block_tree_db,
   196                                          batch_newdb, batch_olddb,
   211     WriteTxIndexMigrationBatches(*
this, block_tree_db,
   212                                  batch_newdb, batch_olddb,
   216         LogPrintf(
"[CANCELLED].\n");
   222     LogPrintf(
"[DONE].\n");
   249     std::vector<std::pair<uint256, CDiskTxPos>> vPos;
   250     vPos.reserve(block.
vtx.size());
   251     for (
const auto& tx : block.
vtx) {
   252         vPos.emplace_back(tx->GetHash(), pos);
   255     return m_db->WriteTxs(vPos);
   263     if (!
m_db->ReadTxPos(tx_hash, postx)) {
   269         return error(
"%s: OpenBlockFile failed", __func__);
   275             return error(
"%s: fseek(...) failed", __func__);
   278     } 
catch (
const std::exception& e) {
   279         return error(
"%s: Deserialize or I/O error - %s", __func__, e.what());
   281     if (tx->GetHash() != tx_hash) {
   282         return error(
"%s: txid mismatch", __func__);
 void SerializationOp(Stream &s, Operation ser_action)
 
CDiskBlockPos GetBlockPos() const
 
bool WriteBlock(const CBlock &block, const CBlockIndex *pindex) override
Write update index entries for a newly connected block. 
 
virtual bool Init()
Initialize internal state from the database and block index. 
 
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
 
constexpr char DB_TXINDEX_BLOCK
 
Batch of changes queued to be written to a CDBWrapper. 
 
unsigned int GetSizeOfCompactSize(uint64_t nSize)
Compact Size size < 253 – 1 byte size <= USHRT_MAX – 3 bytes (253 + 2 bytes) size <= UINT_MAX – 5 ...
 
constexpr char DB_TXINDEX
 
const std::unique_ptr< DB > m_db
 
#define READWRITEAS(type, obj)
 
std::shared_ptr< const CTransaction > CTransactionRef
 
bool Init() override
Override base class init to migrate from old database. 
 
CDBIterator * NewIterator()
 
bool IsNull() const
Return true if the wrapped FILE* is nullptr, false otherwise. 
 
Access to the txindex database (indexes/txindex/) 
 
bool ReadTxPos(const uint256 &txid, CDiskTxPos &pos) const
Read the disk location of the transaction data with the given hash. 
 
size_t GetSerializeSize(const T &t, int nVersion=0)
 
Base class for indices of blockchain data. 
 
FILE * OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly)
Open a block file (blk?????.dat) 
 
bool FindTx(const uint256 &tx_hash, uint256 &block_hash, CTransactionRef &tx) const
Look up a transaction by hash. 
 
Access to the block database (blocks/index/) 
 
bool MigrateData(CBlockTreeDB &block_tree_db, const CBlockLocator &best_locator)
Migrate txindex data from the block tree DB, where it may be for older nodes that have not been upgra...
 
std::unique_ptr< TxIndex > g_txindex
The global transaction index, used in GetTransaction. May be null. 
 
void Write(const K &key, const V &value)
 
BaseIndex::DB & GetDB() const override
 
size_t SizeEstimate() const
 
CDiskTxPos(const CDiskBlockPos &blockIn, unsigned int nTxOffsetIn)
 
bool Read(const K &key, V &value) const
 
bool ReadFlag(const std::string &name, bool &fValue)
 
TxIndex(size_t n_cache_size, bool f_memory=false, bool f_wipe=false)
Constructs the index, which becomes available to be queried. 
 
virtual ~TxIndex() override
 
bool Write(const K &key, const V &value, bool fSync=false)
 
void CompactRange(const K &key_begin, const K &key_end) const
Compact a certain range of keys in the database. 
 
std::vector< CTransactionRef > vtx
 
FILE * Get() const
Get wrapped FILE* without transfer of ownership. 
 
The block chain is a tree shaped structure starting with the genesis block at the root...
 
bool WriteTxs(const std::vector< std::pair< uint256, CDiskTxPos >> &v_pos)
Write a batch of transaction positions to the DB. 
 
DB(size_t n_cache_size, bool f_memory=false, bool f_wipe=false)
 
CBlockLocator GetLocator(const CBlockIndex *pindex=nullptr) const
Return a CBlockLocator that refers to a block in this chain (by default the tip). ...
 
constexpr char DB_BEST_BLOCK
 
std::unique_ptr< CBlockTreeDB > pblocktree
Global variable that points to the active block tree (protected by cs_main) 
 
bool error(const char *fmt, const Args &... args)
 
bool WriteFlag(const std::string &name, bool fValue)
 
const fs::path & GetDataDir(bool fNetSpecific)
 
bool WriteBatch(CDBBatch &batch, bool fSync=false)
 
CClientUIInterface uiInterface
 
CChain & chainActive
The currently-connected chain of blocks (protected by cs_main). 
 
std::unique_ptr< T > MakeUnique(Args &&... args)
Substitute for C++14 std::make_unique. 
 
TxIndex is used to look up transactions included in the blockchain by hash. 
 
Non-refcounted RAII wrapper for FILE*. 
 
std::string _(const char *psz)
Translation function.