/Users/eugenesiegel/btc/bitcoin/src/wallet/feebumper.h
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | // Copyright (c) 2017-2021 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 | 0 |     { | 
| 84 | 0 |         switch (sigversion) { | 
| 85 | 0 |         case SigVersion::BASE: | 
| 86 | 0 |             m_sigs_weight += weight * WITNESS_SCALE_FACTOR; | 
| 87 | 0 |             m_sigs_count += 1 * WITNESS_SCALE_FACTOR; | 
| 88 | 0 |             break; | 
| 89 | 0 |         case SigVersion::WITNESS_V0: | 
| 90 | 0 |             m_sigs_weight += weight; | 
| 91 | 0 |             m_sigs_count++; | 
| 92 | 0 |             break; | 
| 93 | 0 |         case SigVersion::TAPROOT: | 
| 94 | 0 |         case SigVersion::TAPSCRIPT: | 
| 95 | 0 |             assert(false); | 
| 96 | 0 |         } | 
| 97 | 0 |     } | 
| 98 |  |  | 
| 99 |  |     int64_t GetWeightDiffToMax() const | 
| 100 | 0 |     { | 
| 101 |  |         // Note: the witness scaling factor is already accounted for because the count is multiplied by it. | 
| 102 | 0 |         return (/* max signature size=*/ 72 * m_sigs_count) - m_sigs_weight; | 
| 103 | 0 |     } | 
| 104 |  | }; | 
| 105 |  |  | 
| 106 |  | class SignatureWeightChecker : public DeferringSignatureChecker | 
| 107 |  | { | 
| 108 |  | private: | 
| 109 |  |     SignatureWeights& m_weights; | 
| 110 |  |  | 
| 111 |  | public: | 
| 112 | 0 |     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 | 0 |     { | 
| 116 | 0 |         if (m_checker.CheckECDSASignature(sig, pubkey, script, sigversion)) { | 
| 117 | 0 |             m_weights.AddSigWeight(sig.size(), sigversion); | 
| 118 | 0 |             return true; | 
| 119 | 0 |         } | 
| 120 | 0 |         return false; | 
| 121 | 0 |     } | 
| 122 |  | }; | 
| 123 |  |  | 
| 124 |  | } // namespace feebumper | 
| 125 |  | } // namespace wallet | 
| 126 |  |  | 
| 127 |  | #endif // BITCOIN_WALLET_FEEBUMPER_H |