Branch data Line data Source code
# 1 : : // Copyright (c) 2009-2010 Satoshi Nakamoto # 2 : : // Copyright (c) 2009-2020 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 : 19 : { # 15 : 19 : return GetRequiredFeeRate(wallet).GetFee(nTxBytes); # 16 : 19 : } # 17 : : # 18 : : # 19 : : CAmount GetMinimumFee(const CWallet& wallet, unsigned int nTxBytes, const CCoinControl& coin_control, FeeCalculation* feeCalc) # 20 : 6 : { # 21 : 6 : return GetMinimumFeeRate(wallet, coin_control, feeCalc).GetFee(nTxBytes); # 22 : 6 : } # 23 : : # 24 : : CFeeRate GetRequiredFeeRate(const CWallet& wallet) # 25 : 5346 : { # 26 : 5346 : return std::max(wallet.m_min_fee, wallet.chain().relayMinFee()); # 27 : 5346 : } # 28 : : # 29 : : CFeeRate GetMinimumFeeRate(const CWallet& wallet, const CCoinControl& coin_control, FeeCalculation* feeCalc) # 30 : 5644 : { # 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 : 5644 : CFeeRate feerate_needed; # 39 [ + + ]: 5644 : if (coin_control.m_feerate) { // 1. # 40 : 821 : feerate_needed = *(coin_control.m_feerate); # 41 [ + - ]: 821 : if (feeCalc) feeCalc->reason = FeeReason::PAYTXFEE; # 42 : : // Allow to override automatic min/max check over coin control instance # 43 [ + + ]: 821 : if (coin_control.fOverrideFeeRate) return feerate_needed; # 44 : 821 : } # 45 [ + + ][ + + ]: 4823 : 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 : 424 : feerate_needed = wallet.m_pay_tx_fee; # 47 [ + + ]: 424 : if (feeCalc) feeCalc->reason = FeeReason::PAYTXFEE; # 48 : 424 : } # 49 : 4399 : else { // 2. or 4. # 50 : : // We will use smart fee estimation # 51 [ + + ]: 4399 : 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 : 4399 : 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 [ - + ]: 4399 : if (coin_control.m_fee_mode == FeeEstimateMode::CONSERVATIVE) conservative_estimate = true; # 56 [ + + ]: 4399 : else if (coin_control.m_fee_mode == FeeEstimateMode::ECONOMICAL) conservative_estimate = false; # 57 : : # 58 : 4399 : feerate_needed = wallet.chain().estimateSmartFee(target, conservative_estimate, feeCalc); # 59 [ + + ]: 4399 : if (feerate_needed == CFeeRate(0)) { # 60 : : // if we don't have enough data for estimateSmartFee, then use fallback fee # 61 : 2093 : feerate_needed = wallet.m_fallback_fee; # 62 [ + + ]: 2093 : if (feeCalc) feeCalc->reason = FeeReason::FALLBACK; # 63 : : # 64 : : // directly return if fallback fee is disabled (feerate 0 == disabled) # 65 [ + + ]: 2093 : if (wallet.m_fallback_fee == CFeeRate(0)) return feerate_needed; # 66 : 2093 : } # 67 : : // Obey mempool min fee when using smart fee estimation # 68 : 4382 : CFeeRate min_mempool_feerate = wallet.chain().mempoolMinFee(); # 69 [ - + ]: 4382 : 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 : 4382 : } # 74 : : # 75 : : // prevent user from paying a fee below the required fee rate # 76 : 5327 : CFeeRate required_feerate = GetRequiredFeeRate(wallet); # 77 [ + + ]: 5327 : if (required_feerate > feerate_needed) { # 78 : 85 : feerate_needed = required_feerate; # 79 [ + - ]: 85 : if (feeCalc) feeCalc->reason = FeeReason::REQUIRED; # 80 : 85 : } # 81 : 5327 : return feerate_needed; # 82 : 5644 : } # 83 : : # 84 : : CFeeRate GetDiscardRate(const CWallet& wallet) # 85 : 5447 : { # 86 : 5447 : unsigned int highest_target = wallet.chain().estimateMaxBlocks(); # 87 : 5447 : CFeeRate discard_rate = wallet.chain().estimateSmartFee(highest_target, false /* conservative */); # 88 : : // Don't let discard_rate be greater than longest possible fee estimate if we get a valid fee estimate # 89 [ + + ]: 5447 : 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 dustRelayFee # 91 : 5447 : discard_rate = std::max(discard_rate, wallet.chain().relayDustFee()); # 92 : 5447 : return discard_rate; # 93 : 5447 : } # 94 : : } // namespace wallet