Bitcoin ABC 0.32.5
P2P Digital Currency
txindex.cpp
Go to the documentation of this file.
1// Copyright (c) 2017-2018 The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5#include <index/txindex.h>
6
7#include <chain.h>
8#include <clientversion.h>
9#include <common/args.h>
10#include <index/disktxpos.h>
11#include <logging.h>
12#include <node/blockstorage.h>
13#include <validation.h>
14
15constexpr uint8_t DB_TXINDEX{'t'};
16
17std::unique_ptr<TxIndex> g_txindex;
18
20class TxIndex::DB : public BaseIndex::DB {
21public:
22 explicit DB(size_t n_cache_size, bool f_memory = false,
23 bool f_wipe = false);
24
27 bool ReadTxPos(const TxId &txid, CDiskTxPos &pos) const;
28
30 bool WriteTxs(const std::vector<std::pair<TxId, CDiskTxPos>> &v_pos);
31};
32
33TxIndex::DB::DB(size_t n_cache_size, bool f_memory, bool f_wipe)
34 : BaseIndex::DB(gArgs.GetDataDirNet() / "indexes" / "txindex", n_cache_size,
35 f_memory, f_wipe) {}
36
37bool TxIndex::DB::ReadTxPos(const TxId &txid, CDiskTxPos &pos) const {
38 return Read(std::make_pair(DB_TXINDEX, txid), pos);
39}
40
42 const std::vector<std::pair<TxId, CDiskTxPos>> &v_pos) {
43 CDBBatch batch(*this);
44 for (const auto &tuple : v_pos) {
45 batch.Write(std::make_pair(DB_TXINDEX, tuple.first), tuple.second);
46 }
47 return WriteBatch(batch);
48}
49
50TxIndex::TxIndex(std::unique_ptr<interfaces::Chain> chain, size_t n_cache_size,
51 bool f_memory, bool f_wipe)
52 : BaseIndex(std::move(chain), "txindex"),
53 m_db(std::make_unique<TxIndex::DB>(n_cache_size, f_memory, f_wipe)) {}
54
55TxIndex::~TxIndex() = default;
56
57bool TxIndex::WriteBlock(const CBlock &block, const CBlockIndex *pindex) {
58 // Exclude genesis block transaction because outputs are not spendable.
59 if (pindex->nHeight == 0) {
60 return true;
61 }
62
63 CDiskTxPos pos(WITH_LOCK(::cs_main, return pindex->GetBlockPos()),
64 GetSizeOfCompactSize(block.vtx.size()));
65 std::vector<std::pair<TxId, CDiskTxPos>> vPos;
66 vPos.reserve(block.vtx.size());
67 for (const auto &tx : block.vtx) {
68 vPos.emplace_back(tx->GetId(), pos);
70 }
71 return m_db->WriteTxs(vPos);
72}
73
75 return *m_db;
76}
77
78bool TxIndex::FindTx(const TxId &txid, BlockHash &block_hash,
79 CTransactionRef &tx) const {
80 CDiskTxPos postx;
81 if (!m_db->ReadTxPos(txid, postx)) {
82 return false;
83 }
84
87 if (file.IsNull()) {
88 LogError("%s: OpenBlockFile failed\n", __func__);
89 return false;
90 }
91 CBlockHeader header;
92 try {
93 file >> header;
94 if (fseek(file.Get(), postx.nTxOffset, SEEK_CUR)) {
95 LogError("%s: fseek(...) failed\n", __func__);
96 return false;
97 }
98 file >> tx;
99 } catch (const std::exception &e) {
100 LogError("%s: Deserialize or I/O error - %s\n", __func__, e.what());
101 return false;
102 }
103 if (tx->GetId() != txid) {
104 LogError("%s: txid mismatch\n", __func__);
105 return false;
106 }
107 block_hash = header.GetHash();
108 return true;
109}
ArgsManager gArgs
Definition: args.cpp:40
bool IsNull() const
Return true if the wrapped FILE* is nullptr, false otherwise.
Definition: streams.h:557
std::FILE * Get() const
Get wrapped FILE* without transfer of ownership.
Definition: streams.h:554
The database stores a block locator of the chain the database is synced to so that the TxIndex can ef...
Definition: base.h:46
Base class for indices of blockchain data.
Definition: base.h:37
Chainstate * m_chainstate
Definition: base.h:102
Nodes collect new transactions into a block, hash them into a hash tree, and scan through nonce value...
Definition: block.h:23
BlockHash GetHash() const
Definition: block.cpp:11
Definition: block.h:60
std::vector< CTransactionRef > vtx
Definition: block.h:63
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: blockindex.h:25
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: blockindex.h:38
FlatFilePos GetBlockPos() const EXCLUSIVE_LOCKS_REQUIRED(
Definition: blockindex.h:97
Batch of changes queued to be written to a CDBWrapper.
Definition: dbwrapper.h:77
void Write(const K &key, const V &value)
Definition: dbwrapper.h:100
node::BlockManager & m_blockman
Reference to a BlockManager instance which itself is shared across all Chainstate instances.
Definition: validation.h:791
Access to the txindex database (indexes/txindex/)
Definition: txindex.cpp:20
DB(size_t n_cache_size, bool f_memory=false, bool f_wipe=false)
Definition: txindex.cpp:33
bool WriteTxs(const std::vector< std::pair< TxId, CDiskTxPos > > &v_pos)
Write a batch of transaction positions to the DB.
Definition: txindex.cpp:41
bool ReadTxPos(const TxId &txid, CDiskTxPos &pos) const
Read the disk location of the transaction data with the given ID.
Definition: txindex.cpp:37
TxIndex is used to look up transactions included in the blockchain by ID.
Definition: txindex.h:22
bool FindTx(const TxId &txid, BlockHash &block_hash, CTransactionRef &tx) const
Look up a transaction by identifier.
Definition: txindex.cpp:78
BaseIndex::DB & GetDB() const override
Definition: txindex.cpp:74
TxIndex(std::unique_ptr< interfaces::Chain > chain, size_t n_cache_size, bool f_memory=false, bool f_wipe=false)
Constructs the index, which becomes available to be queried.
Definition: txindex.cpp:50
virtual ~TxIndex() override
bool WriteBlock(const CBlock &block, const CBlockIndex *pindex) override
Write update index entries for a newly connected block.
Definition: txindex.cpp:57
const std::unique_ptr< DB > m_db
Definition: txindex.h:27
bool IsBlockPruned(const CBlockIndex &block) const EXCLUSIVE_LOCKS_REQUIRED(void UpdatePruneLock(const std::string &name, const PruneLockInfo &lock_info) EXCLUSIVE_LOCKS_REQUIRED(FILE * OpenBlockFile(const FlatFilePos &pos, bool fReadOnly=false) const
Check whether the block associated with this index entry is pruned or not.
Definition: blockstorage.h:434
static constexpr int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
Definition: clientversion.h:38
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
Definition: cs_main.cpp:7
#define LogError(...)
Definition: logging.h:419
Implement std::hash so RCUPtr can be used as a key for maps or sets.
Definition: rcu.h:259
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:315
uint32_t GetSizeOfCompactSize(uint64_t nSize)
Compact Size size < 253 – 1 byte size <= USHRT_MAX – 3 bytes (253 + 2 bytes) size <= UINT_MAX – 5 byt...
Definition: serialize.h:437
@ SER_DISK
Definition: serialize.h:156
size_t GetSerializeSize(const T &t, int nVersion=0)
Definition: serialize.h:1280
A BlockHash is a unqiue identifier for a block.
Definition: blockhash.h:13
unsigned int nTxOffset
Definition: disktxpos.h:12
A TxId is the identifier of a transaction.
Definition: txid.h:14
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:357
std::unique_ptr< TxIndex > g_txindex
The global transaction index, used in GetTransaction. May be null.
Definition: txindex.cpp:17
constexpr uint8_t DB_TXINDEX
Definition: txindex.cpp:15