Bitcoin Core  27.99.0
P2P Digital Currency
txindex.cpp
Go to the documentation of this file.
1 // Copyright (c) 2017-2022 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 <clientversion.h>
8 #include <common/args.h>
9 #include <index/disktxpos.h>
10 #include <logging.h>
11 #include <node/blockstorage.h>
12 #include <validation.h>
13 
14 constexpr uint8_t DB_TXINDEX{'t'};
15 
16 std::unique_ptr<TxIndex> g_txindex;
17 
18 
20 class TxIndex::DB : public BaseIndex::DB
21 {
22 public:
23  explicit DB(size_t n_cache_size, bool f_memory = false, bool f_wipe = false);
24 
27  bool ReadTxPos(const uint256& txid, CDiskTxPos& pos) const;
28 
30  [[nodiscard]] bool WriteTxs(const std::vector<std::pair<uint256, CDiskTxPos>>& v_pos);
31 };
32 
33 TxIndex::DB::DB(size_t n_cache_size, bool f_memory, bool f_wipe) :
34  BaseIndex::DB(gArgs.GetDataDirNet() / "indexes" / "txindex", n_cache_size, f_memory, f_wipe)
35 {}
36 
37 bool TxIndex::DB::ReadTxPos(const uint256 &txid, CDiskTxPos& pos) const
38 {
39  return Read(std::make_pair(DB_TXINDEX, txid), pos);
40 }
41 
42 bool TxIndex::DB::WriteTxs(const std::vector<std::pair<uint256, CDiskTxPos>>& v_pos)
43 {
44  CDBBatch batch(*this);
45  for (const auto& tuple : v_pos) {
46  batch.Write(std::make_pair(DB_TXINDEX, tuple.first), tuple.second);
47  }
48  return WriteBatch(batch);
49 }
50 
51 TxIndex::TxIndex(std::unique_ptr<interfaces::Chain> chain, size_t n_cache_size, bool f_memory, bool f_wipe)
52  : BaseIndex(std::move(chain), "txindex"), m_db(std::make_unique<TxIndex::DB>(n_cache_size, f_memory, f_wipe))
53 {}
54 
55 TxIndex::~TxIndex() = default;
56 
58 {
59  // Exclude genesis block transaction because outputs are not spendable.
60  if (block.height == 0) return true;
61 
62  assert(block.data);
63  CDiskTxPos pos({block.file_number, block.data_pos}, GetSizeOfCompactSize(block.data->vtx.size()));
64  std::vector<std::pair<uint256, CDiskTxPos>> vPos;
65  vPos.reserve(block.data->vtx.size());
66  for (const auto& tx : block.data->vtx) {
67  vPos.emplace_back(tx->GetHash(), pos);
69  }
70  return m_db->WriteTxs(vPos);
71 }
72 
73 BaseIndex::DB& TxIndex::GetDB() const { return *m_db; }
74 
75 bool TxIndex::FindTx(const uint256& tx_hash, uint256& block_hash, CTransactionRef& tx) const
76 {
77  CDiskTxPos postx;
78  if (!m_db->ReadTxPos(tx_hash, postx)) {
79  return false;
80  }
81 
82  AutoFile file{m_chainstate->m_blockman.OpenBlockFile(postx, true)};
83  if (file.IsNull()) {
84  LogError("%s: OpenBlockFile failed\n", __func__);
85  return false;
86  }
87  CBlockHeader header;
88  try {
89  file >> header;
90  if (fseek(file.Get(), postx.nTxOffset, SEEK_CUR)) {
91  LogError("%s: fseek(...) failed\n", __func__);
92  return false;
93  }
94  file >> TX_WITH_WITNESS(tx);
95  } catch (const std::exception& e) {
96  LogError("%s: Deserialize or I/O error - %s\n", __func__, e.what());
97  return false;
98  }
99  if (tx->GetHash() != tx_hash) {
100  LogError("%s: txid mismatch\n", __func__);
101  return false;
102  }
103  block_hash = header.GetHash();
104  return true;
105 }
ArgsManager gArgs
Definition: args.cpp:41
Non-refcounted RAII wrapper for FILE*.
Definition: streams.h:389
The database stores a block locator of the chain the database is synced to so that the index can effi...
Definition: base.h:51
Base class for indices of blockchain data.
Definition: base.h:41
Chainstate * m_chainstate
Definition: base.h:101
Nodes collect new transactions into a block, hash them into a hash tree, and scan through nonce value...
Definition: block.h:22
uint256 GetHash() const
Definition: block.cpp:11
std::vector< CTransactionRef > vtx
Definition: block.h:72
Batch of changes queued to be written to a CDBWrapper.
Definition: dbwrapper.h:73
void Write(const K &key, const V &value)
Definition: dbwrapper.h:99
node::BlockManager & m_blockman
Reference to a BlockManager instance which itself is shared across all Chainstate instances.
Definition: validation.h:521
Access to the txindex database (indexes/txindex/)
Definition: txindex.cpp:21
bool WriteTxs(const std::vector< std::pair< uint256, CDiskTxPos >> &v_pos)
Write a batch of transaction positions to the DB.
Definition: txindex.cpp:42
DB(size_t n_cache_size, bool f_memory=false, bool f_wipe=false)
Definition: txindex.cpp:33
bool ReadTxPos(const uint256 &txid, CDiskTxPos &pos) const
Read the disk location of the transaction data with the given hash.
Definition: txindex.cpp:37
TxIndex is used to look up transactions included in the blockchain by hash.
Definition: txindex.h:18
bool FindTx(const uint256 &tx_hash, uint256 &block_hash, CTransactionRef &tx) const
Look up a transaction by hash.
Definition: txindex.cpp:75
BaseIndex::DB & GetDB() const override
Definition: txindex.cpp:73
bool CustomAppend(const interfaces::BlockInfo &block) override
Write update index entries for a newly connected block.
Definition: txindex.cpp:57
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:51
virtual ~TxIndex() override
const std::unique_ptr< DB > m_db
Definition: txindex.h:20
bool IsBlockPruned(const CBlockIndex &block) EXCLUSIVE_LOCKS_REQUIRED(void UpdatePruneLock(const std::string &name, const PruneLockInfo &lock_info) EXCLUSIVE_LOCKS_REQUIRED(AutoFile OpenBlockFile(const FlatFilePos &pos, bool fReadOnly=false) const
Check whether the block associated with this index entry is pruned or not.
Definition: blockstorage.h:353
256-bit opaque blob.
Definition: uint256.h:106
#define LogError(...)
Definition: logging.h:241
static constexpr TransactionSerParams TX_WITH_WITNESS
Definition: transaction.h:195
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:423
size_t GetSerializeSize(const T &t)
Definition: serialize.h:1116
constexpr unsigned int 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:310
unsigned int nTxOffset
Definition: disktxpos.h:13
Block data sent with blockConnected, blockDisconnected notifications.
Definition: chain.h:84
unsigned data_pos
Definition: chain.h:89
const CBlock * data
Definition: chain.h:90
std::unique_ptr< TxIndex > g_txindex
The global transaction index, used in GetTransaction. May be null.
Definition: txindex.cpp:16
constexpr uint8_t DB_TXINDEX
Definition: txindex.cpp:14
assert(!tx.IsCoinBase())