Bitcoin Core 22.99.0
P2P Digital Currency
txindex.cpp
Go to the documentation of this file.
1// Copyright (c) 2017-2020 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 <index/disktxpos.h>
8#include <node/blockstorage.h>
9#include <util/system.h>
10#include <validation.h>
11
12constexpr uint8_t DB_TXINDEX{'t'};
13
14std::unique_ptr<TxIndex> g_txindex;
15
16
19{
20public:
21 explicit DB(size_t n_cache_size, bool f_memory = false, bool f_wipe = false);
22
25 bool ReadTxPos(const uint256& txid, CDiskTxPos& pos) const;
26
28 bool WriteTxs(const std::vector<std::pair<uint256, CDiskTxPos>>& v_pos);
29};
30
31TxIndex::DB::DB(size_t n_cache_size, bool f_memory, bool f_wipe) :
32 BaseIndex::DB(gArgs.GetDataDirNet() / "indexes" / "txindex", n_cache_size, f_memory, f_wipe)
33{}
34
35bool TxIndex::DB::ReadTxPos(const uint256 &txid, CDiskTxPos& pos) const
36{
37 return Read(std::make_pair(DB_TXINDEX, txid), pos);
38}
39
40bool TxIndex::DB::WriteTxs(const std::vector<std::pair<uint256, CDiskTxPos>>& v_pos)
41{
42 CDBBatch batch(*this);
43 for (const auto& tuple : v_pos) {
44 batch.Write(std::make_pair(DB_TXINDEX, tuple.first), tuple.second);
45 }
46 return WriteBatch(batch);
47}
48
49TxIndex::TxIndex(size_t n_cache_size, bool f_memory, bool f_wipe)
50 : m_db(std::make_unique<TxIndex::DB>(n_cache_size, f_memory, f_wipe))
51{}
52
54
55bool TxIndex::WriteBlock(const CBlock& block, const CBlockIndex* pindex)
56{
57 // Exclude genesis block transaction because outputs are not spendable.
58 if (pindex->nHeight == 0) return true;
59
60 CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size()));
61 std::vector<std::pair<uint256, CDiskTxPos>> vPos;
62 vPos.reserve(block.vtx.size());
63 for (const auto& tx : block.vtx) {
64 vPos.emplace_back(tx->GetHash(), pos);
66 }
67 return m_db->WriteTxs(vPos);
68}
69
70BaseIndex::DB& TxIndex::GetDB() const { return *m_db; }
71
72bool TxIndex::FindTx(const uint256& tx_hash, uint256& block_hash, CTransactionRef& tx) const
73{
74 CDiskTxPos postx;
75 if (!m_db->ReadTxPos(tx_hash, postx)) {
76 return false;
77 }
78
80 if (file.IsNull()) {
81 return error("%s: OpenBlockFile failed", __func__);
82 }
83 CBlockHeader header;
84 try {
85 file >> header;
86 if (fseek(file.Get(), postx.nTxOffset, SEEK_CUR)) {
87 return error("%s: fseek(...) failed", __func__);
88 }
89 file >> tx;
90 } catch (const std::exception& e) {
91 return error("%s: Deserialize or I/O error - %s", __func__, e.what());
92 }
93 if (tx->GetHash() != tx_hash) {
94 return error("%s: txid mismatch", __func__);
95 }
96 block_hash = header.GetHash();
97 return true;
98}
FILE * OpenBlockFile(const FlatFilePos &pos, bool fReadOnly)
Open a block file (blk?????.dat)
The database stores a block locator of the chain the database is synced to so that the index can effi...
Definition: base.h:38
Base class for indices of blockchain data.
Definition: base.h:28
Non-refcounted RAII wrapper for FILE*.
Definition: streams.h:565
bool IsNull() const
Return true if the wrapped FILE* is nullptr, false otherwise.
Definition: streams.h:609
FILE * Get() const
Get wrapped FILE* without transfer of ownership.
Definition: streams.h:605
Nodes collect new transactions into a block, hash them into a hash tree, and scan through nonce value...
Definition: block.h:21
uint256 GetHash() const
Definition: block.cpp:11
Definition: block.h:63
std::vector< CTransactionRef > vtx
Definition: block.h:66
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: chain.h:146
FlatFilePos GetBlockPos() const
Definition: chain.h:223
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:158
Batch of changes queued to be written to a CDBWrapper.
Definition: dbwrapper.h:48
void Write(const K &key, const V &value)
Definition: dbwrapper.h:73
Access to the txindex database (indexes/txindex/)
Definition: txindex.cpp:19
DB(size_t n_cache_size, bool f_memory=false, bool f_wipe=false)
Definition: txindex.cpp:31
bool WriteTxs(const std::vector< std::pair< uint256, CDiskTxPos > > &v_pos)
Write a batch of transaction positions to the DB.
Definition: txindex.cpp:40
bool ReadTxPos(const uint256 &txid, CDiskTxPos &pos) const
Read the disk location of the transaction data with the given hash.
Definition: txindex.cpp:35
TxIndex is used to look up transactions included in the blockchain by hash.
Definition: txindex.h:16
TxIndex(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:49
bool FindTx(const uint256 &tx_hash, uint256 &block_hash, CTransactionRef &tx) const
Look up a transaction by hash.
Definition: txindex.cpp:72
BaseIndex::DB & GetDB() const override
Definition: txindex.cpp:70
virtual ~TxIndex() override
Definition: txindex.cpp:53
bool WriteBlock(const CBlock &block, const CBlockIndex *pindex) override
Write update index entries for a newly connected block.
Definition: txindex.cpp:55
const std::unique_ptr< DB > m_db
Definition: txindex.h:18
256-bit opaque blob.
Definition: uint256.h:124
static const int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
Definition: clientversion.h:33
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:386
@ SER_DISK
Definition: serialize.h:139
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:240
size_t GetSerializeSize(const T &t, int nVersion=0)
Definition: serialize.h:1080
unsigned int nTxOffset
Definition: disktxpos.h:13
bool error(const char *fmt, const Args &... args)
Definition: system.h:49
std::unique_ptr< TxIndex > g_txindex
The global transaction index, used in GetTransaction. May be null.
Definition: txindex.cpp:14
constexpr uint8_t DB_TXINDEX
Definition: txindex.cpp:12
ArgsManager gArgs
Definition: system.cpp:85