txospenderindex.h raw
1 // Copyright (c) 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 #ifndef BITCOIN_INDEX_TXOSPENDERINDEX_H
6 #define BITCOIN_INDEX_TXOSPENDERINDEX_H
7
8 #include <index/base.h>
9 #include <interfaces/chain.h>
10 #include <primitives/transaction.h>
11 #include <uint256.h>
12 #include <util/expected.h>
13
14 #include <cstddef>
15 #include <cstdint>
16 #include <memory>
17 #include <optional>
18 #include <string>
19 #include <utility>
20 #include <vector>
21
22 struct CDiskTxPos;
23
24 static constexpr bool DEFAULT_TXOSPENDERINDEX{false};
25
26 struct TxoSpender {
27 CTransactionRef tx;
28 uint256 block_hash;
29 };
30
31 /**
32 * TxoSpenderIndex is used to look up which transaction spent a given output.
33 * The index is written to a LevelDB database and, for each input of each transaction in a block,
34 * records the outpoint that is spent and the hash of the spending transaction.
35 */
36 class TxoSpenderIndex final : public BaseIndex
37 {
38 private:
39 std::unique_ptr<BaseIndex::DB> m_db;
40 std::pair<uint64_t, uint64_t> m_siphash_key;
41 bool AllowPrune() const override { return false; }
42 void WriteSpenderInfos(const std::vector<std::pair<COutPoint, CDiskTxPos>>& items);
43 void EraseSpenderInfos(const std::vector<std::pair<COutPoint, CDiskTxPos>>& items);
44 util::Expected<TxoSpender, std::string> ReadTransaction(const CDiskTxPos& pos) const;
45
46 protected:
47 interfaces::Chain::NotifyOptions CustomOptions() override;
48
49 bool CustomAppend(const interfaces::BlockInfo& block) override;
50
51 bool CustomRemove(const interfaces::BlockInfo& block) override;
52
53 BaseIndex::DB& GetDB() const override;
54
55 public:
56 explicit TxoSpenderIndex(std::unique_ptr<interfaces::Chain> chain, size_t n_cache_size, bool f_memory = false, bool f_wipe = false);
57
58 /**
59 * Search the index for a transaction that spends the given outpoint.
60 *
61 * @param[in] txo The outpoint to search for.
62 *
63 * @return std::nullopt if the outpoint has not been spent on-chain.
64 * std::optional{TxoSpender} if the output has been spent on-chain. Contains the spending transaction
65 * and the block it was confirmed in.
66 * util::Unexpected{error} if something unexpected happened (i.e. disk or deserialization error).
67 */
68 util::Expected<std::optional<TxoSpender>, std::string> FindSpender(const COutPoint& txo) const;
69 };
70
71 /// The global txo spender index. May be null.
72 extern std::unique_ptr<TxoSpenderIndex> g_txospenderindex;
73
74
75 #endif // BITCOIN_INDEX_TXOSPENDERINDEX_H
76