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