fees.cpp raw

   1  // Copyright (c) 2009-2010 Satoshi Nakamoto
   2  // Copyright (c) 2009-present 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  {
  15      return GetRequiredFeeRate(wallet).GetFee(static_cast<int32_t>(nTxBytes));
  16  }
  17  
  18  
  19  CAmount GetMinimumFee(const CWallet& wallet, unsigned int nTxBytes, const CCoinControl& coin_control, FeeCalculation* feeCalc)
  20  {
  21      return GetMinimumFeeRate(wallet, coin_control, feeCalc).GetFee(static_cast<int32_t>(nTxBytes));
  22  }
  23  
  24  CFeeRate GetRequiredFeeRate(const CWallet& wallet)
  25  {
  26      return std::max(wallet.m_min_fee, wallet.chain().relayMinFee());
  27  }
  28  
  29  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_confirm_target (user-set member variable of wallet)
  35         The first parameter that is set is used.
  36      */
  37      CFeeRate feerate_needed;
  38      if (coin_control.m_feerate) { // 1.
  39          feerate_needed = *(coin_control.m_feerate);
  40          // Allow to override automatic min/max check over coin control instance
  41          if (coin_control.fOverrideFeeRate) return feerate_needed;
  42      }
  43      else { // 2. or 3.
  44          // We will use smart fee estimation
  45          unsigned int target = coin_control.m_confirm_target ? *coin_control.m_confirm_target : wallet.m_confirm_target;
  46          // By default estimates are economical iff we are signaling opt-in-RBF
  47          bool conservative_estimate = !coin_control.m_signal_bip125_rbf.value_or(wallet.m_signal_rbf);
  48          // Allow to override the default fee estimate mode over the CoinControl instance
  49          if (coin_control.m_fee_mode == FeeEstimateMode::CONSERVATIVE) conservative_estimate = true;
  50          else if (coin_control.m_fee_mode == FeeEstimateMode::ECONOMICAL) conservative_estimate = false;
  51  
  52          feerate_needed = wallet.chain().estimateSmartFee(target, conservative_estimate, feeCalc);
  53          if (feerate_needed == CFeeRate(0)) {
  54              // if we don't have enough data for estimateSmartFee, then use fallback fee
  55              feerate_needed = wallet.m_fallback_fee;
  56              if (feeCalc) feeCalc->reason = FeeReason::FALLBACK;
  57  
  58              // directly return if fallback fee is disabled (feerate 0 == disabled)
  59              if (wallet.m_fallback_fee == CFeeRate(0)) return feerate_needed;
  60          }
  61          // Obey mempool min fee when using smart fee estimation
  62          CFeeRate min_mempool_feerate = wallet.chain().mempoolMinFee();
  63          if (feerate_needed < min_mempool_feerate) {
  64              feerate_needed = min_mempool_feerate;
  65              if (feeCalc) feeCalc->reason = FeeReason::MEMPOOL_MIN;
  66          }
  67      }
  68  
  69      // prevent user from paying a fee below the required fee rate
  70      CFeeRate required_feerate = GetRequiredFeeRate(wallet);
  71      if (required_feerate > feerate_needed) {
  72          feerate_needed = required_feerate;
  73          if (feeCalc) feeCalc->reason = FeeReason::REQUIRED;
  74      }
  75      return feerate_needed;
  76  }
  77  
  78  CFeeRate GetDiscardRate(const CWallet& wallet)
  79  {
  80      unsigned int highest_target = wallet.chain().estimateMaxBlocks();
  81      CFeeRate discard_rate = wallet.chain().estimateSmartFee(highest_target, /*conservative=*/false);
  82      // Don't let discard_rate be greater than longest possible fee estimate if we get a valid fee estimate
  83      discard_rate = (discard_rate == CFeeRate(0)) ? wallet.m_discard_rate : std::min(discard_rate, wallet.m_discard_rate);
  84      // Discard rate must be at least dust relay feerate
  85      discard_rate = std::max(discard_rate, wallet.chain().relayDustFee());
  86      return discard_rate;
  87  }
  88  } // namespace wallet
  89