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