Branch data Line data Source code
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 : 0 : CAmount GetRequiredFee(const CWallet& wallet, unsigned int nTxBytes)
14 : : {
15 : 0 : return GetRequiredFeeRate(wallet).GetFee(nTxBytes);
16 : : }
17 : :
18 : :
19 : 0 : CAmount GetMinimumFee(const CWallet& wallet, unsigned int nTxBytes, const CCoinControl& coin_control, FeeCalculation* feeCalc)
20 : : {
21 : 0 : return GetMinimumFeeRate(wallet, coin_control, feeCalc).GetFee(nTxBytes);
22 : : }
23 : :
24 : 0 : CFeeRate GetRequiredFeeRate(const CWallet& wallet)
25 : : {
26 [ # # ]: 0 : return std::max(wallet.m_min_fee, wallet.chain().relayMinFee());
27 : : }
28 : :
29 : 15 : CFeeRate GetMinimumFeeRate(const CWallet& wallet, const CCoinControl& coin_control, FeeCalculation* feeCalc)
30 : : {
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 [ + + ]: 15 : CFeeRate feerate_needed;
39 [ + + ]: 15 : if (coin_control.m_feerate) { // 1.
40 [ + - ]: 8 : feerate_needed = *(coin_control.m_feerate);
41 [ + - ]: 8 : if (feeCalc) feeCalc->reason = FeeReason::PAYTXFEE;
42 : : // Allow to override automatic min/max check over coin control instance
43 [ + - ]: 8 : if (coin_control.fOverrideFeeRate) return feerate_needed;
44 : : }
45 [ + - - + ]: 7 : 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 : : }
49 : : else { // 2. or 4.
50 : : // We will use smart fee estimation
51 [ - + ]: 7 : 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 [ - + ]: 7 : 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 [ + - ]: 7 : if (coin_control.m_fee_mode == FeeEstimateMode::CONSERVATIVE) conservative_estimate = true;
56 [ - + ]: 7 : else if (coin_control.m_fee_mode == FeeEstimateMode::ECONOMICAL) conservative_estimate = false;
57 : :
58 : 7 : feerate_needed = wallet.chain().estimateSmartFee(target, conservative_estimate, feeCalc);
59 [ + - ]: 7 : if (feerate_needed == CFeeRate(0)) {
60 : : // if we don't have enough data for estimateSmartFee, then use fallback fee
61 : 7 : feerate_needed = wallet.m_fallback_fee;
62 [ + - ]: 7 : if (feeCalc) feeCalc->reason = FeeReason::FALLBACK;
63 : :
64 : : // directly return if fallback fee is disabled (feerate 0 == disabled)
65 [ + - ]: 7 : if (wallet.m_fallback_fee == CFeeRate(0)) return feerate_needed;
66 : : }
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 : : }
73 : : }
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 : : }
81 : 0 : return feerate_needed;
82 : : }
83 : :
84 : 15 : CFeeRate GetDiscardRate(const CWallet& wallet)
85 : : {
86 : 15 : unsigned int highest_target = wallet.chain().estimateMaxBlocks();
87 : 15 : 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 [ + - - - ]: 15 : 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 [ + - ]: 15 : discard_rate = std::max(discard_rate, wallet.chain().relayDustFee());
92 : 15 : return discard_rate;
93 : : }
94 : : } // namespace wallet
|