aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Morcos <morcos@chaincode.com>2017-06-13 11:28:30 -0400
committerAlex Morcos <morcos@chaincode.com>2017-07-06 22:20:23 -0400
commitd507c301bc49c72ed7303658a309e7d204134f80 (patch)
tree33e3d8fed65c98f105bf80bcfb2dfb3f32c98cf9
parentcfaef69ace6c52aeb4ce347597c6dae61bdce744 (diff)
Introduce a fee estimate mode.
GetMinimumFee now passes the conservative argument into estimateSmartFee. Call CalculateEstimateType(mode) before calling GetMinimumFee or estimateSmartFee to determine the value of this argument. CCoinControl can now be used to control this mode.
-rw-r--r--src/policy/fees.h7
-rw-r--r--src/qt/coincontroldialog.cpp6
-rw-r--r--src/qt/sendcoinsdialog.cpp3
-rw-r--r--src/qt/walletmodel.cpp1
-rw-r--r--src/wallet/coincontrol.h4
-rw-r--r--src/wallet/feebumper.cpp3
-rw-r--r--src/wallet/wallet.cpp20
-rw-r--r--src/wallet/wallet.h6
8 files changed, 42 insertions, 8 deletions
diff --git a/src/policy/fees.h b/src/policy/fees.h
index 2029ce3744..8a98e55520 100644
--- a/src/policy/fees.h
+++ b/src/policy/fees.h
@@ -90,6 +90,13 @@ enum class FeeReason {
std::string StringForFeeReason(FeeReason reason);
+/* Used to determine type of fee estimation requested */
+enum class FeeEstimateMode {
+ UNSET, //! Use default settings based on other criteria
+ ECONOMICAL, //! Force estimateSmartFee to use non-conservative estimates
+ CONSERVATIVE, //! Force estimateSmartFee to use conservative estimates
+};
+
/* Used to return detailed information about a feerate bucket */
struct EstimatorBucket
{
diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp
index 10a8d6b887..477cee1c04 100644
--- a/src/qt/coincontroldialog.cpp
+++ b/src/qt/coincontroldialog.cpp
@@ -490,6 +490,8 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
else nBytesInputs += 148;
}
+ bool conservative_estimate = CalculateEstimateType(FeeEstimateMode::UNSET);
+
// calculation
if (nQuantity > 0)
{
@@ -510,7 +512,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
nBytes -= 34;
// Fee
- nPayFee = CWallet::GetMinimumFee(nBytes, coinControl->nConfirmTarget, ::mempool, ::feeEstimator, nullptr /* FeeCalculation */, false /* ignoreGlobalPayTxFee */);
+ nPayFee = CWallet::GetMinimumFee(nBytes, coinControl->nConfirmTarget, ::mempool, ::feeEstimator, nullptr /* FeeCalculation */, false /* ignoreGlobalPayTxFee */, conservative_estimate);
if (nPayAmount > 0)
{
@@ -585,7 +587,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
if (payTxFee.GetFeePerK() > 0)
dFeeVary = (double)std::max(CWallet::GetRequiredFee(1000), payTxFee.GetFeePerK()) / 1000;
else {
- dFeeVary = (double)std::max(CWallet::GetRequiredFee(1000), ::feeEstimator.estimateSmartFee(coinControl->nConfirmTarget, NULL, ::mempool).GetFeePerK()) / 1000;
+ dFeeVary = (double)std::max(CWallet::GetRequiredFee(1000), ::feeEstimator.estimateSmartFee(coinControl->nConfirmTarget, NULL, ::mempool, conservative_estimate).GetFeePerK()) / 1000;
}
QString toolTip4 = tr("Can vary +/- %1 satoshi(s) per input.").arg(dFeeVary);
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index 12d2d0f31c..d9439fe248 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -652,7 +652,8 @@ void SendCoinsDialog::updateSmartFeeLabel()
int nBlocksToConfirm = ui->sliderSmartFee->maximum() - ui->sliderSmartFee->value() + 2;
FeeCalculation feeCalc;
- CFeeRate feeRate = ::feeEstimator.estimateSmartFee(nBlocksToConfirm, &feeCalc, ::mempool);
+ bool conservative_estimate = CalculateEstimateType(FeeEstimateMode::UNSET);
+ CFeeRate feeRate = ::feeEstimator.estimateSmartFee(nBlocksToConfirm, &feeCalc, ::mempool, conservative_estimate);
if (feeRate <= CFeeRate(0)) // not enough data => minfee
{
ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(),
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
index 7eff783fe8..354225090f 100644
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -19,6 +19,7 @@
#include "keystore.h"
#include "validation.h"
#include "net.h" // for g_connman
+#include "policy/fees.h"
#include "policy/rbf.h"
#include "sync.h"
#include "ui_interface.h"
diff --git a/src/wallet/coincontrol.h b/src/wallet/coincontrol.h
index cb4719ae90..bdd01bec12 100644
--- a/src/wallet/coincontrol.h
+++ b/src/wallet/coincontrol.h
@@ -6,6 +6,7 @@
#define BITCOIN_WALLET_COINCONTROL_H
#include "policy/feerate.h"
+#include "policy/fees.h"
#include "primitives/transaction.h"
#include "wallet/wallet.h"
@@ -26,6 +27,8 @@ public:
int nConfirmTarget;
//! Signal BIP-125 replace by fee.
bool signalRbf;
+ //! Fee estimation mode to control arguments to estimateSmartFee
+ FeeEstimateMode m_fee_mode;
CCoinControl()
{
@@ -42,6 +45,7 @@ public:
fOverrideFeeRate = false;
nConfirmTarget = 0;
signalRbf = fWalletRbf;
+ m_fee_mode = FeeEstimateMode::UNSET;
}
bool HasSelected() const
diff --git a/src/wallet/feebumper.cpp b/src/wallet/feebumper.cpp
index 6a9e6cf9ff..a36f6798f0 100644
--- a/src/wallet/feebumper.cpp
+++ b/src/wallet/feebumper.cpp
@@ -165,7 +165,8 @@ CFeeBumper::CFeeBumper(const CWallet *pWallet, const uint256 txidIn, int newConf
nNewFee = totalFee;
nNewFeeRate = CFeeRate(totalFee, maxNewTxSize);
} else {
- nNewFee = CWallet::GetMinimumFee(maxNewTxSize, newConfirmTarget, mempool, ::feeEstimator, nullptr, ignoreGlobalPayTxFee);
+ bool conservative_estimate = CalculateEstimateType(FeeEstimateMode::UNSET);
+ nNewFee = CWallet::GetMinimumFee(maxNewTxSize, newConfirmTarget, mempool, ::feeEstimator, nullptr /* FeeCalculation */, ignoreGlobalPayTxFee, conservative_estimate);
nNewFeeRate = CFeeRate(nNewFee, maxNewTxSize);
// New fee rate must be at least old rate + minimum incremental relay rate
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 4b00404d2a..a43b5398e0 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -2724,7 +2724,10 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
if (coinControl && coinControl->nConfirmTarget > 0)
currentConfirmationTarget = coinControl->nConfirmTarget;
- CAmount nFeeNeeded = GetMinimumFee(nBytes, currentConfirmationTarget, ::mempool, ::feeEstimator, &feeCalc, false /* ignoreGlobalPayTxFee */);
+ // Allow to override the default fee estimate mode over the CoinControl instance
+ bool conservative_estimate = CalculateEstimateType(coinControl ? coinControl->m_fee_mode : FeeEstimateMode::UNSET);
+
+ CAmount nFeeNeeded = GetMinimumFee(nBytes, currentConfirmationTarget, ::mempool, ::feeEstimator, &feeCalc, false /* ignoreGlobalPayTxFee */, conservative_estimate);
if (coinControl && coinControl->fOverrideFeeRate)
nFeeNeeded = coinControl->nFeeRate.GetFee(nBytes);
@@ -2905,13 +2908,13 @@ CAmount CWallet::GetRequiredFee(unsigned int nTxBytes)
return std::max(minTxFee.GetFee(nTxBytes), ::minRelayTxFee.GetFee(nTxBytes));
}
-CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation *feeCalc, bool ignoreGlobalPayTxFee)
+CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation *feeCalc, bool ignoreGlobalPayTxFee, bool conservative_estimate)
{
// payTxFee is the user-set global for desired feerate
CAmount nFeeNeeded = payTxFee.GetFee(nTxBytes);
// User didn't set: use -txconfirmtarget to estimate...
if (nFeeNeeded == 0 || ignoreGlobalPayTxFee) {
- nFeeNeeded = estimator.estimateSmartFee(nConfirmTarget, feeCalc, pool, true).GetFee(nTxBytes);
+ nFeeNeeded = estimator.estimateSmartFee(nConfirmTarget, feeCalc, pool, conservative_estimate).GetFee(nTxBytes);
// ... unless we don't have enough mempool data for estimatefee, then use fallbackFee
if (nFeeNeeded == 0) {
nFeeNeeded = fallbackFee.GetFee(nTxBytes);
@@ -4154,3 +4157,14 @@ bool CMerkleTx::AcceptToMemoryPool(const CAmount& nAbsurdFee, CValidationState&
{
return ::AcceptToMemoryPool(mempool, state, tx, true, NULL, NULL, false, nAbsurdFee);
}
+
+bool CalculateEstimateType(FeeEstimateMode mode) {
+ switch (mode) {
+ case FeeEstimateMode::UNSET:
+ case FeeEstimateMode::CONSERVATIVE:
+ return true;
+ case FeeEstimateMode::ECONOMICAL:
+ return false;
+ }
+ return true;
+}
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 232673a2f7..813bf530ac 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -80,6 +80,7 @@ class CTxMemPool;
class CBlockPolicyEstimator;
class CWalletTx;
struct FeeCalculation;
+enum class FeeEstimateMode;
/** (client) version numbers for particular wallet features */
enum WalletFeature
@@ -963,7 +964,7 @@ public:
* Estimate the minimum fee considering user set parameters
* and the required fee
*/
- static CAmount GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation *feeCalc, bool ignoreGlobalPayTxFee);
+ static CAmount GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation *feeCalc, bool ignoreGlobalPayTxFee, bool conservative_estimate);
/**
* Return the minimum required fee taking into account the
* floating relay fee and user set minimum transaction fee
@@ -1211,4 +1212,7 @@ bool CWallet::DummySignTx(CMutableTransaction &txNew, const ContainerType &coins
}
return true;
}
+
+bool CalculateEstimateType(FeeEstimateMode mode);
+
#endif // BITCOIN_WALLET_WALLET_H