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.