Skip to content

Commit d507c30

Browse files
committed
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.
1 parent cfaef69 commit d507c30

File tree

8 files changed

+42
-8
lines changed

8 files changed

+42
-8
lines changed

src/policy/fees.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,13 @@ enum class FeeReason {
9090

9191
std::string StringForFeeReason(FeeReason reason);
9292

93+
/* Used to determine type of fee estimation requested */
94+
enum class FeeEstimateMode {
95+
UNSET, //! Use default settings based on other criteria
96+
ECONOMICAL, //! Force estimateSmartFee to use non-conservative estimates
97+
CONSERVATIVE, //! Force estimateSmartFee to use conservative estimates
98+
};
99+
93100
/* Used to return detailed information about a feerate bucket */
94101
struct EstimatorBucket
95102
{

src/qt/coincontroldialog.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,8 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
490490
else nBytesInputs += 148;
491491
}
492492

493+
bool conservative_estimate = CalculateEstimateType(FeeEstimateMode::UNSET);
494+
493495
// calculation
494496
if (nQuantity > 0)
495497
{
@@ -510,7 +512,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
510512
nBytes -= 34;
511513

512514
// Fee
513-
nPayFee = CWallet::GetMinimumFee(nBytes, coinControl->nConfirmTarget, ::mempool, ::feeEstimator, nullptr /* FeeCalculation */, false /* ignoreGlobalPayTxFee */);
515+
nPayFee = CWallet::GetMinimumFee(nBytes, coinControl->nConfirmTarget, ::mempool, ::feeEstimator, nullptr /* FeeCalculation */, false /* ignoreGlobalPayTxFee */, conservative_estimate);
514516

515517
if (nPayAmount > 0)
516518
{
@@ -585,7 +587,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
585587
if (payTxFee.GetFeePerK() > 0)
586588
dFeeVary = (double)std::max(CWallet::GetRequiredFee(1000), payTxFee.GetFeePerK()) / 1000;
587589
else {
588-
dFeeVary = (double)std::max(CWallet::GetRequiredFee(1000), ::feeEstimator.estimateSmartFee(coinControl->nConfirmTarget, NULL, ::mempool).GetFeePerK()) / 1000;
590+
dFeeVary = (double)std::max(CWallet::GetRequiredFee(1000), ::feeEstimator.estimateSmartFee(coinControl->nConfirmTarget, NULL, ::mempool, conservative_estimate).GetFeePerK()) / 1000;
589591
}
590592
QString toolTip4 = tr("Can vary +/- %1 satoshi(s) per input.").arg(dFeeVary);
591593

src/qt/sendcoinsdialog.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,8 @@ void SendCoinsDialog::updateSmartFeeLabel()
652652

653653
int nBlocksToConfirm = ui->sliderSmartFee->maximum() - ui->sliderSmartFee->value() + 2;
654654
FeeCalculation feeCalc;
655-
CFeeRate feeRate = ::feeEstimator.estimateSmartFee(nBlocksToConfirm, &feeCalc, ::mempool);
655+
bool conservative_estimate = CalculateEstimateType(FeeEstimateMode::UNSET);
656+
CFeeRate feeRate = ::feeEstimator.estimateSmartFee(nBlocksToConfirm, &feeCalc, ::mempool, conservative_estimate);
656657
if (feeRate <= CFeeRate(0)) // not enough data => minfee
657658
{
658659
ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(),

src/qt/walletmodel.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "keystore.h"
2020
#include "validation.h"
2121
#include "net.h" // for g_connman
22+
#include "policy/fees.h"
2223
#include "policy/rbf.h"
2324
#include "sync.h"
2425
#include "ui_interface.h"

src/wallet/coincontrol.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#define BITCOIN_WALLET_COINCONTROL_H
77

88
#include "policy/feerate.h"
9+
#include "policy/fees.h"
910
#include "primitives/transaction.h"
1011
#include "wallet/wallet.h"
1112

@@ -26,6 +27,8 @@ class CCoinControl
2627
int nConfirmTarget;
2728
//! Signal BIP-125 replace by fee.
2829
bool signalRbf;
30+
//! Fee estimation mode to control arguments to estimateSmartFee
31+
FeeEstimateMode m_fee_mode;
2932

3033
CCoinControl()
3134
{
@@ -42,6 +45,7 @@ class CCoinControl
4245
fOverrideFeeRate = false;
4346
nConfirmTarget = 0;
4447
signalRbf = fWalletRbf;
48+
m_fee_mode = FeeEstimateMode::UNSET;
4549
}
4650

4751
bool HasSelected() const

src/wallet/feebumper.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,8 @@ CFeeBumper::CFeeBumper(const CWallet *pWallet, const uint256 txidIn, int newConf
165165
nNewFee = totalFee;
166166
nNewFeeRate = CFeeRate(totalFee, maxNewTxSize);
167167
} else {
168-
nNewFee = CWallet::GetMinimumFee(maxNewTxSize, newConfirmTarget, mempool, ::feeEstimator, nullptr, ignoreGlobalPayTxFee);
168+
bool conservative_estimate = CalculateEstimateType(FeeEstimateMode::UNSET);
169+
nNewFee = CWallet::GetMinimumFee(maxNewTxSize, newConfirmTarget, mempool, ::feeEstimator, nullptr /* FeeCalculation */, ignoreGlobalPayTxFee, conservative_estimate);
169170
nNewFeeRate = CFeeRate(nNewFee, maxNewTxSize);
170171

171172
// New fee rate must be at least old rate + minimum incremental relay rate

src/wallet/wallet.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2724,7 +2724,10 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
27242724
if (coinControl && coinControl->nConfirmTarget > 0)
27252725
currentConfirmationTarget = coinControl->nConfirmTarget;
27262726

2727-
CAmount nFeeNeeded = GetMinimumFee(nBytes, currentConfirmationTarget, ::mempool, ::feeEstimator, &feeCalc, false /* ignoreGlobalPayTxFee */);
2727+
// Allow to override the default fee estimate mode over the CoinControl instance
2728+
bool conservative_estimate = CalculateEstimateType(coinControl ? coinControl->m_fee_mode : FeeEstimateMode::UNSET);
2729+
2730+
CAmount nFeeNeeded = GetMinimumFee(nBytes, currentConfirmationTarget, ::mempool, ::feeEstimator, &feeCalc, false /* ignoreGlobalPayTxFee */, conservative_estimate);
27282731
if (coinControl && coinControl->fOverrideFeeRate)
27292732
nFeeNeeded = coinControl->nFeeRate.GetFee(nBytes);
27302733

@@ -2905,13 +2908,13 @@ CAmount CWallet::GetRequiredFee(unsigned int nTxBytes)
29052908
return std::max(minTxFee.GetFee(nTxBytes), ::minRelayTxFee.GetFee(nTxBytes));
29062909
}
29072910

2908-
CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation *feeCalc, bool ignoreGlobalPayTxFee)
2911+
CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation *feeCalc, bool ignoreGlobalPayTxFee, bool conservative_estimate)
29092912
{
29102913
// payTxFee is the user-set global for desired feerate
29112914
CAmount nFeeNeeded = payTxFee.GetFee(nTxBytes);
29122915
// User didn't set: use -txconfirmtarget to estimate...
29132916
if (nFeeNeeded == 0 || ignoreGlobalPayTxFee) {
2914-
nFeeNeeded = estimator.estimateSmartFee(nConfirmTarget, feeCalc, pool, true).GetFee(nTxBytes);
2917+
nFeeNeeded = estimator.estimateSmartFee(nConfirmTarget, feeCalc, pool, conservative_estimate).GetFee(nTxBytes);
29152918
// ... unless we don't have enough mempool data for estimatefee, then use fallbackFee
29162919
if (nFeeNeeded == 0) {
29172920
nFeeNeeded = fallbackFee.GetFee(nTxBytes);
@@ -4154,3 +4157,14 @@ bool CMerkleTx::AcceptToMemoryPool(const CAmount& nAbsurdFee, CValidationState&
41544157
{
41554158
return ::AcceptToMemoryPool(mempool, state, tx, true, NULL, NULL, false, nAbsurdFee);
41564159
}
4160+
4161+
bool CalculateEstimateType(FeeEstimateMode mode) {
4162+
switch (mode) {
4163+
case FeeEstimateMode::UNSET:
4164+
case FeeEstimateMode::CONSERVATIVE:
4165+
return true;
4166+
case FeeEstimateMode::ECONOMICAL:
4167+
return false;
4168+
}
4169+
return true;
4170+
}

src/wallet/wallet.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ class CTxMemPool;
8080
class CBlockPolicyEstimator;
8181
class CWalletTx;
8282
struct FeeCalculation;
83+
enum class FeeEstimateMode;
8384

8485
/** (client) version numbers for particular wallet features */
8586
enum WalletFeature
@@ -963,7 +964,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface
963964
* Estimate the minimum fee considering user set parameters
964965
* and the required fee
965966
*/
966-
static CAmount GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation *feeCalc, bool ignoreGlobalPayTxFee);
967+
static CAmount GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation *feeCalc, bool ignoreGlobalPayTxFee, bool conservative_estimate);
967968
/**
968969
* Return the minimum required fee taking into account the
969970
* floating relay fee and user set minimum transaction fee
@@ -1211,4 +1212,7 @@ bool CWallet::DummySignTx(CMutableTransaction &txNew, const ContainerType &coins
12111212
}
12121213
return true;
12131214
}
1215+
1216+
bool CalculateEstimateType(FeeEstimateMode mode);
1217+
12141218
#endif // BITCOIN_WALLET_WALLET_H

0 commit comments

Comments
 (0)