/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 uint256& 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 uint256& 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 uint256& txid, |
71 | | CMutableTransaction&& mtx, |
72 | | std::vector<bilingual_str>& errors, |
73 | | uint256& 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 |