diff options
Diffstat (limited to 'src/wallet/feebumper.h')
-rw-r--r-- | src/wallet/feebumper.h | 66 |
1 files changed, 64 insertions, 2 deletions
diff --git a/src/wallet/feebumper.h b/src/wallet/feebumper.h index 191878a137..760ab58e5c 100644 --- a/src/wallet/feebumper.h +++ b/src/wallet/feebumper.h @@ -5,6 +5,8 @@ #ifndef BITCOIN_WALLET_FEEBUMPER_H #define BITCOIN_WALLET_FEEBUMPER_H +#include <consensus/consensus.h> +#include <script/interpreter.h> #include <primitives/transaction.h> class uint256; @@ -31,14 +33,25 @@ enum class Result //! Return whether transaction can be bumped. bool TransactionCanBeBumped(const CWallet& wallet, const uint256& txid); -//! Create bumpfee transaction based on feerate estimates. +/** Create bumpfee transaction based on feerate estimates. + * + * @param[in] wallet The wallet to use for this bumping + * @param[in] txid The txid of the transaction to bump + * @param[in] coin_control A CCoinControl object which provides feerates and other information used for coin selection + * @param[out] errors Errors + * @param[out] old_fee The fee the original transaction pays + * @param[out] new_fee the fee that the bump transaction pays + * @param[out] mtx The bump transaction itself + * @param[in] require_mine Whether the original transaction must consist of inputs that can be spent by the wallet + */ Result CreateRateBumpTransaction(CWallet& wallet, const uint256& txid, const CCoinControl& coin_control, std::vector<bilingual_str>& errors, CAmount& old_fee, CAmount& new_fee, - CMutableTransaction& mtx); + CMutableTransaction& mtx, + bool require_mine); //! Sign the new transaction, //! @return false if the tx couldn't be found or if it was @@ -55,6 +68,55 @@ Result CommitTransaction(CWallet& wallet, std::vector<bilingual_str>& errors, uint256& bumped_txid); +struct SignatureWeights +{ +private: + int m_sigs_count{0}; + int64_t m_sigs_weight{0}; + +public: + void AddSigWeight(const size_t weight, const SigVersion sigversion) + { + switch (sigversion) { + case SigVersion::BASE: + m_sigs_weight += weight * WITNESS_SCALE_FACTOR; + m_sigs_count += 1 * WITNESS_SCALE_FACTOR; + break; + case SigVersion::WITNESS_V0: + m_sigs_weight += weight; + m_sigs_count++; + break; + case SigVersion::TAPROOT: + case SigVersion::TAPSCRIPT: + assert(false); + } + } + + int64_t GetWeightDiffToMax() const + { + // Note: the witness scaling factor is already accounted for because the count is multiplied by it. + return (/* max signature size=*/ 72 * m_sigs_count) - m_sigs_weight; + } +}; + +class SignatureWeightChecker : public DeferringSignatureChecker +{ +private: + SignatureWeights& m_weights; + +public: + SignatureWeightChecker(SignatureWeights& weights, const BaseSignatureChecker& checker) : DeferringSignatureChecker(checker), m_weights(weights) {} + + bool CheckECDSASignature(const std::vector<unsigned char>& sig, const std::vector<unsigned char>& pubkey, const CScript& script, SigVersion sigversion) const override + { + if (m_checker.CheckECDSASignature(sig, pubkey, script, sigversion)) { + m_weights.AddSigWeight(sig.size(), sigversion); + return true; + } + return false; + } +}; + } // namespace feebumper } // namespace wallet |