/ src / wallet / feebumper.h
feebumper.h
  1  // Copyright (c) 2017-present 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_WALLET_FEEBUMPER_H
  6  #define BITCOIN_WALLET_FEEBUMPER_H
  7  
  8  #include <consensus/consensus.h>
  9  #include <script/interpreter.h>
 10  #include <primitives/transaction.h>
 11  
 12  class uint256;
 13  enum class FeeEstimateMode;
 14  struct bilingual_str;
 15  
 16  namespace wallet {
 17  class CCoinControl;
 18  class CWallet;
 19  class CWalletTx;
 20  
 21  namespace feebumper {
 22  
 23  enum class Result
 24  {
 25      OK,
 26      INVALID_ADDRESS_OR_KEY,
 27      INVALID_REQUEST,
 28      INVALID_PARAMETER,
 29      WALLET_ERROR,
 30      MISC_ERROR,
 31  };
 32  
 33  //! Return whether transaction can be bumped.
 34  bool TransactionCanBeBumped(const CWallet& wallet, const Txid& txid);
 35  
 36  /** Create bumpfee transaction based on feerate estimates.
 37   *
 38   * @param[in] wallet The wallet to use for this bumping
 39   * @param[in] txid The txid of the transaction to bump
 40   * @param[in] coin_control A CCoinControl object which provides feerates and other information used for coin selection
 41   * @param[out] errors Errors
 42   * @param[out] old_fee The fee the original transaction pays
 43   * @param[out] new_fee the fee that the bump transaction pays
 44   * @param[out] mtx The bump transaction itself
 45   * @param[in] require_mine Whether the original transaction must consist of inputs that can be spent by the wallet
 46   * @param[in] outputs Vector of new outputs to replace the bumped transaction's outputs
 47   * @param[in] original_change_index The position of the change output to deduct the fee from in the transaction being bumped
 48   */
 49  Result CreateRateBumpTransaction(CWallet& wallet,
 50      const Txid& txid,
 51      const CCoinControl& coin_control,
 52      std::vector<bilingual_str>& errors,
 53      CAmount& old_fee,
 54      CAmount& new_fee,
 55      CMutableTransaction& mtx,
 56      bool require_mine,
 57      const std::vector<CTxOut>& outputs,
 58      std::optional<uint32_t> original_change_index = std::nullopt);
 59  
 60  //! Sign the new transaction,
 61  //! @return false if the tx couldn't be found or if it was
 62  //! impossible to create the signature(s)
 63  bool SignTransaction(CWallet& wallet, CMutableTransaction& mtx);
 64  
 65  //! Commit the bumpfee transaction.
 66  //! @return success in case of CWallet::CommitTransaction was successful,
 67  //! but sets errors if the tx could not be added to the mempool (will try later)
 68  //! or if the old transaction could not be marked as replaced.
 69  Result CommitTransaction(CWallet& wallet,
 70      const Txid& txid,
 71      CMutableTransaction&& mtx,
 72      std::vector<bilingual_str>& errors,
 73      Txid& bumped_txid);
 74  
 75  struct SignatureWeights
 76  {
 77  private:
 78      int m_sigs_count{0};
 79      int64_t m_sigs_weight{0};
 80  
 81  public:
 82      void AddSigWeight(const size_t weight, const SigVersion sigversion)
 83      {
 84          switch (sigversion) {
 85          case SigVersion::BASE:
 86              m_sigs_weight += weight * WITNESS_SCALE_FACTOR;
 87              m_sigs_count += 1 * WITNESS_SCALE_FACTOR;
 88              break;
 89          case SigVersion::WITNESS_V0:
 90              m_sigs_weight += weight;
 91              m_sigs_count++;
 92              break;
 93          case SigVersion::TAPROOT:
 94          case SigVersion::TAPSCRIPT:
 95              assert(false);
 96          }
 97      }
 98  
 99      int64_t GetWeightDiffToMax() const
100      {
101          // Note: the witness scaling factor is already accounted for because the count is multiplied by it.
102          return (/* max signature size=*/ 72 * m_sigs_count) - m_sigs_weight;
103      }
104  };
105  
106  class SignatureWeightChecker : public DeferringSignatureChecker
107  {
108  private:
109      SignatureWeights& m_weights;
110  
111  public:
112      SignatureWeightChecker(SignatureWeights& weights, const BaseSignatureChecker& checker) : DeferringSignatureChecker(checker), m_weights(weights) {}
113  
114      bool CheckECDSASignature(const std::vector<unsigned char>& sig, const std::vector<unsigned char>& pubkey, const CScript& script, SigVersion sigversion) const override
115      {
116          if (m_checker.CheckECDSASignature(sig, pubkey, script, sigversion)) {
117              m_weights.AddSigWeight(sig.size(), sigversion);
118              return true;
119          }
120          return false;
121      }
122  };
123  
124  } // namespace feebumper
125  } // namespace wallet
126  
127  #endif // BITCOIN_WALLET_FEEBUMPER_H