/root/bitcoin/src/wallet/fees.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) 2009-2010 Satoshi Nakamoto |
2 | | // Copyright (c) 2009-2022 The Bitcoin Core developers |
3 | | // Distributed under the MIT software license, see the accompanying |
4 | | // file COPYING or http://www.opensource.org/licenses/mit-license.php. |
5 | | |
6 | | #include <wallet/fees.h> |
7 | | |
8 | | #include <wallet/coincontrol.h> |
9 | | #include <wallet/wallet.h> |
10 | | |
11 | | |
12 | | namespace wallet { |
13 | | CAmount GetRequiredFee(const CWallet& wallet, unsigned int nTxBytes) |
14 | 0 | { |
15 | 0 | return GetRequiredFeeRate(wallet).GetFee(nTxBytes); |
16 | 0 | } |
17 | | |
18 | | |
19 | | CAmount GetMinimumFee(const CWallet& wallet, unsigned int nTxBytes, const CCoinControl& coin_control, FeeCalculation* feeCalc) |
20 | 0 | { |
21 | 0 | return GetMinimumFeeRate(wallet, coin_control, feeCalc).GetFee(nTxBytes); |
22 | 0 | } |
23 | | |
24 | | CFeeRate GetRequiredFeeRate(const CWallet& wallet) |
25 | 0 | { |
26 | 0 | return std::max(wallet.m_min_fee, wallet.chain().relayMinFee()); |
27 | 0 | } |
28 | | |
29 | | CFeeRate GetMinimumFeeRate(const CWallet& wallet, const CCoinControl& coin_control, FeeCalculation* feeCalc) |
30 | 0 | { |
31 | | /* User control of how to calculate fee uses the following parameter precedence: |
32 | | 1. coin_control.m_feerate |
33 | | 2. coin_control.m_confirm_target |
34 | | 3. m_pay_tx_fee (user-set member variable of wallet) |
35 | | 4. m_confirm_target (user-set member variable of wallet) |
36 | | The first parameter that is set is used. |
37 | | */ |
38 | 0 | CFeeRate feerate_needed; |
39 | 0 | if (coin_control.m_feerate) { // 1. |
40 | 0 | feerate_needed = *(coin_control.m_feerate); |
41 | 0 | if (feeCalc) feeCalc->reason = FeeReason::PAYTXFEE; |
42 | | // Allow to override automatic min/max check over coin control instance |
43 | 0 | if (coin_control.fOverrideFeeRate) return feerate_needed; |
44 | 0 | } |
45 | 0 | else if (!coin_control.m_confirm_target && wallet.m_pay_tx_fee != CFeeRate(0)) { // 3. TODO: remove magic value of 0 for wallet member m_pay_tx_fee |
46 | 0 | feerate_needed = wallet.m_pay_tx_fee; |
47 | 0 | if (feeCalc) feeCalc->reason = FeeReason::PAYTXFEE; |
48 | 0 | } |
49 | 0 | else { // 2. or 4. |
50 | | // We will use smart fee estimation |
51 | 0 | unsigned int target = coin_control.m_confirm_target ? *coin_control.m_confirm_target : wallet.m_confirm_target; |
52 | | // By default estimates are economical iff we are signaling opt-in-RBF |
53 | 0 | bool conservative_estimate = !coin_control.m_signal_bip125_rbf.value_or(wallet.m_signal_rbf); |
54 | | // Allow to override the default fee estimate mode over the CoinControl instance |
55 | 0 | if (coin_control.m_fee_mode == FeeEstimateMode::CONSERVATIVE) conservative_estimate = true; |
56 | 0 | else if (coin_control.m_fee_mode == FeeEstimateMode::ECONOMICAL) conservative_estimate = false; |
57 | |
|
58 | 0 | feerate_needed = wallet.chain().estimateSmartFee(target, conservative_estimate, feeCalc); |
59 | 0 | if (feerate_needed == CFeeRate(0)) { |
60 | | // if we don't have enough data for estimateSmartFee, then use fallback fee |
61 | 0 | feerate_needed = wallet.m_fallback_fee; |
62 | 0 | if (feeCalc) feeCalc->reason = FeeReason::FALLBACK; |
63 | | |
64 | | // directly return if fallback fee is disabled (feerate 0 == disabled) |
65 | 0 | if (wallet.m_fallback_fee == CFeeRate(0)) return feerate_needed; |
66 | 0 | } |
67 | | // Obey mempool min fee when using smart fee estimation |
68 | 0 | CFeeRate min_mempool_feerate = wallet.chain().mempoolMinFee(); |
69 | 0 | if (feerate_needed < min_mempool_feerate) { |
70 | 0 | feerate_needed = min_mempool_feerate; |
71 | 0 | if (feeCalc) feeCalc->reason = FeeReason::MEMPOOL_MIN; |
72 | 0 | } |
73 | 0 | } |
74 | | |
75 | | // prevent user from paying a fee below the required fee rate |
76 | 0 | CFeeRate required_feerate = GetRequiredFeeRate(wallet); |
77 | 0 | if (required_feerate > feerate_needed) { |
78 | 0 | feerate_needed = required_feerate; |
79 | 0 | if (feeCalc) feeCalc->reason = FeeReason::REQUIRED; |
80 | 0 | } |
81 | 0 | return feerate_needed; |
82 | 0 | } |
83 | | |
84 | | CFeeRate GetDiscardRate(const CWallet& wallet) |
85 | 0 | { |
86 | 0 | unsigned int highest_target = wallet.chain().estimateMaxBlocks(); |
87 | 0 | CFeeRate discard_rate = wallet.chain().estimateSmartFee(highest_target, /*conservative=*/false); |
88 | | // Don't let discard_rate be greater than longest possible fee estimate if we get a valid fee estimate |
89 | 0 | discard_rate = (discard_rate == CFeeRate(0)) ? wallet.m_discard_rate : std::min(discard_rate, wallet.m_discard_rate); |
90 | | // Discard rate must be at least dust relay feerate |
91 | 0 | discard_rate = std::max(discard_rate, wallet.chain().relayDustFee()); |
92 | 0 | return discard_rate; |
93 | 0 | } |
94 | | } // namespace wallet |