Skip to content

Commit 476cb35

Browse files
committed
Merge #12909: wallet: Make fee settings to be non-static members
fac0db0 wallet: Make fee settings non-static members (MarcoFalke) Pull request description: The wallet header defined some globals (they were called "settings"), that should be class members instead. This commit is hopefully only refactoring, apart from a multiwallet bugfix: Calling the rpc `settxfee` for one wallet, would set (and change) the fee rate for all loaded wallets. (See added test case) Tree-SHA512: 4ab6ec2f5c714742396ded5e451ec3b1ceb771e3696492de29889d866de4365b3fbe4a2784d085c8b8bd11b1ebb8a1fec99ab2c62eee716791cfc67c0cf29e1b
2 parents d1d54ae + fac0db0 commit 476cb35

File tree

16 files changed

+186
-187
lines changed

16 files changed

+186
-187
lines changed

src/interfaces/node.cpp

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -191,20 +191,6 @@ class NodeImpl : public Node
191191
}
192192
}
193193
bool getNetworkActive() override { return g_connman && g_connman->GetNetworkActive(); }
194-
unsigned int getTxConfirmTarget() override { CHECK_WALLET(return ::nTxConfirmTarget); }
195-
CAmount getRequiredFee(unsigned int tx_bytes) override { CHECK_WALLET(return GetRequiredFee(tx_bytes)); }
196-
CAmount getMinimumFee(unsigned int tx_bytes,
197-
const CCoinControl& coin_control,
198-
int* returned_target,
199-
FeeReason* reason) override
200-
{
201-
FeeCalculation fee_calc;
202-
CAmount result;
203-
CHECK_WALLET(result = GetMinimumFee(tx_bytes, coin_control, ::mempool, ::feeEstimator, &fee_calc));
204-
if (returned_target) *returned_target = fee_calc.returnedTarget;
205-
if (reason) *reason = fee_calc.reason;
206-
return result;
207-
}
208194
CAmount getMaxTxFee() override { return ::maxTxFee; }
209195
CFeeRate estimateSmartFee(int num_blocks, bool conservative, int* returned_target = nullptr) override
210196
{

src/interfaces/node.h

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,9 @@ class Coin;
2626
class RPCTimerInterface;
2727
class UniValue;
2828
class proxyType;
29-
enum class FeeReason;
3029
struct CNodeStateStats;
3130

3231
namespace interfaces {
33-
3432
class Handler;
3533
class Wallet;
3634

@@ -152,18 +150,6 @@ class Node
152150
//! Get network active.
153151
virtual bool getNetworkActive() = 0;
154152

155-
//! Get tx confirm target.
156-
virtual unsigned int getTxConfirmTarget() = 0;
157-
158-
//! Get required fee.
159-
virtual CAmount getRequiredFee(unsigned int tx_bytes) = 0;
160-
161-
//! Get minimum fee.
162-
virtual CAmount getMinimumFee(unsigned int tx_bytes,
163-
const CCoinControl& coin_control,
164-
int* returned_target,
165-
FeeReason* reason) = 0;
166-
167153
//! Get max tx fee.
168154
virtual CAmount getMaxTxFee() = 0;
169155

src/interfaces/wallet.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include <consensus/validation.h>
1010
#include <interfaces/handler.h>
1111
#include <net.h>
12+
#include <policy/feerate.h>
13+
#include <policy/fees.h>
1214
#include <policy/policy.h>
1315
#include <primitives/transaction.h>
1416
#include <script/ismine.h>
@@ -20,6 +22,7 @@
2022
#include <uint256.h>
2123
#include <validation.h>
2224
#include <wallet/feebumper.h>
25+
#include <wallet/fees.h>
2326
#include <wallet/wallet.h>
2427

2528
namespace interfaces {
@@ -403,6 +406,20 @@ class WalletImpl : public Wallet
403406
}
404407
return result;
405408
}
409+
CAmount getRequiredFee(unsigned int tx_bytes) override { return GetRequiredFee(m_wallet, tx_bytes); }
410+
CAmount getMinimumFee(unsigned int tx_bytes,
411+
const CCoinControl& coin_control,
412+
int* returned_target,
413+
FeeReason* reason) override
414+
{
415+
FeeCalculation fee_calc;
416+
CAmount result;
417+
result = GetMinimumFee(m_wallet, tx_bytes, coin_control, ::mempool, ::feeEstimator, &fee_calc);
418+
if (returned_target) *returned_target = fee_calc.returnedTarget;
419+
if (reason) *reason = fee_calc.reason;
420+
return result;
421+
}
422+
unsigned int getConfirmTarget() override { return m_wallet.m_confirm_target; }
406423
bool hdEnabled() override { return m_wallet.IsHDEnabled(); }
407424
OutputType getDefaultAddressType() override { return m_wallet.m_default_address_type; }
408425
OutputType getDefaultChangeType() override { return m_wallet.m_default_change_type; }

src/interfaces/wallet.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@
2222
#include <vector>
2323

2424
class CCoinControl;
25+
class CFeeRate;
2526
class CKey;
2627
class CWallet;
28+
enum class FeeReason;
2729
enum class OutputType;
2830
struct CRecipient;
2931

@@ -218,6 +220,18 @@ class Wallet
218220
//! Return wallet transaction output information.
219221
virtual std::vector<WalletTxOut> getCoins(const std::vector<COutPoint>& outputs) = 0;
220222

223+
//! Get required fee.
224+
virtual CAmount getRequiredFee(unsigned int tx_bytes) = 0;
225+
226+
//! Get minimum fee.
227+
virtual CAmount getMinimumFee(unsigned int tx_bytes,
228+
const CCoinControl& coin_control,
229+
int* returned_target,
230+
FeeReason* reason) = 0;
231+
232+
//! Get tx confirm target.
233+
virtual unsigned int getConfirmTarget() = 0;
234+
221235
// Return whether HD enabled.
222236
virtual bool hdEnabled() = 0;
223237

src/qt/coincontroldialog.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
509509
nBytes -= 34;
510510

511511
// Fee
512-
nPayFee = model->node().getMinimumFee(nBytes, *coinControl(), nullptr /* returned_target */, nullptr /* reason */);
512+
nPayFee = model->wallet().getMinimumFee(nBytes, *coinControl(), nullptr /* returned_target */, nullptr /* reason */);
513513

514514
if (nPayAmount > 0)
515515
{

src/qt/sendcoinsdialog.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ SendCoinsDialog::SendCoinsDialog(const PlatformStyle *_platformStyle, QWidget *p
114114
if (!settings.contains("nSmartFeeSliderPosition"))
115115
settings.setValue("nSmartFeeSliderPosition", 0);
116116
if (!settings.contains("nTransactionFee"))
117-
settings.setValue("nTransactionFee", (qint64)DEFAULT_TRANSACTION_FEE);
117+
settings.setValue("nTransactionFee", (qint64)DEFAULT_PAY_TX_FEE);
118118
if (!settings.contains("fPayOnlyMinFee"))
119119
settings.setValue("fPayOnlyMinFee", false);
120120
ui->groupFee->setId(ui->radioSmartFee, 0);
@@ -175,7 +175,7 @@ void SendCoinsDialog::setModel(WalletModel *_model)
175175
connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(coinControlUpdateLabels()));
176176
connect(ui->optInRBF, SIGNAL(stateChanged(int)), this, SLOT(updateSmartFeeLabel()));
177177
connect(ui->optInRBF, SIGNAL(stateChanged(int)), this, SLOT(coinControlUpdateLabels()));
178-
ui->customFee->setSingleStep(model->node().getRequiredFee(1000));
178+
ui->customFee->setSingleStep(model->wallet().getRequiredFee(1000));
179179
updateFeeSectionControls();
180180
updateMinFeeLabel();
181181
updateSmartFeeLabel();
@@ -193,7 +193,7 @@ void SendCoinsDialog::setModel(WalletModel *_model)
193193
settings.remove("nSmartFeeSliderPosition");
194194
}
195195
if (settings.value("nConfTarget").toInt() == 0)
196-
ui->confTargetSelector->setCurrentIndex(getIndexForConfTarget(model->node().getTxConfirmTarget()));
196+
ui->confTargetSelector->setCurrentIndex(getIndexForConfTarget(model->wallet().getConfirmTarget()));
197197
else
198198
ui->confTargetSelector->setCurrentIndex(getIndexForConfTarget(settings.value("nConfTarget").toInt()));
199199
}
@@ -629,7 +629,7 @@ void SendCoinsDialog::useAvailableBalance(SendCoinsEntry* entry)
629629

630630
void SendCoinsDialog::setMinimumFee()
631631
{
632-
ui->customFee->setValue(model->node().getRequiredFee(1000));
632+
ui->customFee->setValue(model->wallet().getRequiredFee(1000));
633633
}
634634

635635
void SendCoinsDialog::updateFeeSectionControls()
@@ -661,7 +661,7 @@ void SendCoinsDialog::updateMinFeeLabel()
661661
{
662662
if (model && model->getOptionsModel())
663663
ui->checkBoxMinimumFee->setText(tr("Pay only the required fee of %1").arg(
664-
BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), model->node().getRequiredFee(1000)) + "/kB")
664+
BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), model->wallet().getRequiredFee(1000)) + "/kB")
665665
);
666666
}
667667

@@ -675,7 +675,7 @@ void SendCoinsDialog::updateCoinControlState(CCoinControl& ctrl)
675675
// Avoid using global defaults when sending money from the GUI
676676
// Either custom fee will be used or if not selected, the confirmation target from dropdown box
677677
ctrl.m_confirm_target = getConfTargetForIndex(ui->confTargetSelector->currentIndex());
678-
ctrl.signalRbf = ui->optInRBF->isChecked();
678+
ctrl.m_signal_bip125_rbf = ui->optInRBF->isChecked();
679679
}
680680

681681
void SendCoinsDialog::updateSmartFeeLabel()
@@ -687,7 +687,7 @@ void SendCoinsDialog::updateSmartFeeLabel()
687687
coin_control.m_feerate.reset(); // Explicitly use only fee estimation rate for smart fee labels
688688
int returned_target;
689689
FeeReason reason;
690-
CFeeRate feeRate = CFeeRate(model->node().getMinimumFee(1000, coin_control, &returned_target, &reason));
690+
CFeeRate feeRate = CFeeRate(model->wallet().getMinimumFee(1000, coin_control, &returned_target, &reason));
691691

692692
ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), feeRate.GetFeePerK()) + "/kB");
693693

src/qt/walletmodel.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ bool WalletModel::saveReceiveRequest(const std::string &sAddress, const int64_t
486486
bool WalletModel::bumpFee(uint256 hash)
487487
{
488488
CCoinControl coin_control;
489-
coin_control.signalRbf = true;
489+
coin_control.m_signal_bip125_rbf = true;
490490
std::vector<std::string> errors;
491491
CAmount old_fee;
492492
CAmount new_fee;

src/wallet/coincontrol.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ class CCoinControl
2626
bool fAllowWatchOnly;
2727
//! Override automatic min/max checks on fee, m_feerate must be set if true
2828
bool fOverrideFeeRate;
29-
//! Override the default payTxFee if set
29+
//! Override the wallet's m_pay_tx_fee if set
3030
boost::optional<CFeeRate> m_feerate;
3131
//! Override the default confirmation target if set
3232
boost::optional<unsigned int> m_confirm_target;
33-
//! Signal BIP-125 replace by fee.
34-
bool signalRbf;
33+
//! Override the wallet's m_signal_rbf if set
34+
boost::optional<bool> m_signal_bip125_rbf;
3535
//! Fee estimation mode to control arguments to estimateSmartFee
3636
FeeEstimateMode m_fee_mode;
3737

@@ -50,7 +50,7 @@ class CCoinControl
5050
m_feerate.reset();
5151
fOverrideFeeRate = false;
5252
m_confirm_target.reset();
53-
signalRbf = fWalletRbf;
53+
m_signal_bip125_rbf.reset();
5454
m_fee_mode = FeeEstimateMode::UNSET;
5555
}
5656

src/wallet/feebumper.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ Result CreateTransaction(const CWallet* wallet, const uint256& txid, const CCoin
134134
FormatMoney(minTotalFee), FormatMoney(nOldFeeRate.GetFee(maxNewTxSize)), FormatMoney(::incrementalRelayFee.GetFee(maxNewTxSize))));
135135
return Result::INVALID_PARAMETER;
136136
}
137-
CAmount requiredFee = GetRequiredFee(maxNewTxSize);
137+
CAmount requiredFee = GetRequiredFee(*wallet, maxNewTxSize);
138138
if (total_fee < requiredFee) {
139139
errors.push_back(strprintf("Insufficient totalFee (cannot be less than required fee %s)",
140140
FormatMoney(requiredFee)));
@@ -143,7 +143,7 @@ Result CreateTransaction(const CWallet* wallet, const uint256& txid, const CCoin
143143
new_fee = total_fee;
144144
nNewFeeRate = CFeeRate(total_fee, maxNewTxSize);
145145
} else {
146-
new_fee = GetMinimumFee(maxNewTxSize, coin_control, mempool, ::feeEstimator, nullptr /* FeeCalculation */);
146+
new_fee = GetMinimumFee(*wallet, maxNewTxSize, coin_control, mempool, ::feeEstimator, nullptr /* FeeCalculation */);
147147
nNewFeeRate = CFeeRate(new_fee, maxNewTxSize);
148148

149149
// New fee rate must be at least old rate + minimum incremental relay rate
@@ -194,14 +194,14 @@ Result CreateTransaction(const CWallet* wallet, const uint256& txid, const CCoin
194194

195195
// If the output would become dust, discard it (converting the dust to fee)
196196
poutput->nValue -= nDelta;
197-
if (poutput->nValue <= GetDustThreshold(*poutput, GetDiscardRate(::feeEstimator))) {
197+
if (poutput->nValue <= GetDustThreshold(*poutput, GetDiscardRate(*wallet, ::feeEstimator))) {
198198
LogPrint(BCLog::RPC, "Bumping fee and discarding dust output\n");
199199
new_fee += poutput->nValue;
200200
mtx.vout.erase(mtx.vout.begin() + nOutput);
201201
}
202202

203203
// Mark new tx not replaceable, if requested.
204-
if (!coin_control.signalRbf) {
204+
if (!coin_control.m_signal_bip125_rbf.get_value_or(wallet->m_signal_rbf)) {
205205
for (auto& input : mtx.vin) {
206206
if (input.nSequence < 0xfffffffe) input.nSequence = 0xfffffffe;
207207
}

src/wallet/fees.cpp

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@
1313
#include <wallet/wallet.h>
1414

1515

16-
CAmount GetRequiredFee(unsigned int nTxBytes)
16+
CAmount GetRequiredFee(const CWallet& wallet, unsigned int nTxBytes)
1717
{
18-
return std::max(CWallet::minTxFee.GetFee(nTxBytes), ::minRelayTxFee.GetFee(nTxBytes));
18+
return GetRequiredFeeRate(wallet).GetFee(nTxBytes);
1919
}
2020

2121

22-
CAmount GetMinimumFee(unsigned int nTxBytes, const CCoinControl& coin_control, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation *feeCalc)
22+
CAmount GetMinimumFee(const CWallet& wallet, unsigned int nTxBytes, const CCoinControl& coin_control, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation* feeCalc)
2323
{
24-
CAmount fee_needed = GetMinimumFeeRate(coin_control, pool, estimator, feeCalc).GetFee(nTxBytes);
24+
CAmount fee_needed = GetMinimumFeeRate(wallet, coin_control, pool, estimator, feeCalc).GetFee(nTxBytes);
2525
// Always obey the maximum
2626
if (fee_needed > maxTxFee) {
2727
fee_needed = maxTxFee;
@@ -30,48 +30,48 @@ CAmount GetMinimumFee(unsigned int nTxBytes, const CCoinControl& coin_control, c
3030
return fee_needed;
3131
}
3232

33-
CFeeRate GetRequiredFeeRate()
33+
CFeeRate GetRequiredFeeRate(const CWallet& wallet)
3434
{
35-
return std::max(CWallet::minTxFee, ::minRelayTxFee);
35+
return std::max(wallet.m_min_fee, ::minRelayTxFee);
3636
}
3737

38-
CFeeRate GetMinimumFeeRate(const CCoinControl& coin_control, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation *feeCalc)
38+
CFeeRate GetMinimumFeeRate(const CWallet& wallet, const CCoinControl& coin_control, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation* feeCalc)
3939
{
4040
/* User control of how to calculate fee uses the following parameter precedence:
4141
1. coin_control.m_feerate
4242
2. coin_control.m_confirm_target
43-
3. payTxFee (user-set global variable)
44-
4. nTxConfirmTarget (user-set global variable)
43+
3. m_pay_tx_fee (user-set member variable of wallet)
44+
4. m_confirm_target (user-set member variable of wallet)
4545
The first parameter that is set is used.
4646
*/
47-
CFeeRate feerate_needed ;
47+
CFeeRate feerate_needed;
4848
if (coin_control.m_feerate) { // 1.
4949
feerate_needed = *(coin_control.m_feerate);
5050
if (feeCalc) feeCalc->reason = FeeReason::PAYTXFEE;
5151
// Allow to override automatic min/max check over coin control instance
5252
if (coin_control.fOverrideFeeRate) return feerate_needed;
5353
}
54-
else if (!coin_control.m_confirm_target && ::payTxFee != CFeeRate(0)) { // 3. TODO: remove magic value of 0 for global payTxFee
55-
feerate_needed = ::payTxFee;
54+
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
55+
feerate_needed = wallet.m_pay_tx_fee;
5656
if (feeCalc) feeCalc->reason = FeeReason::PAYTXFEE;
5757
}
5858
else { // 2. or 4.
5959
// We will use smart fee estimation
60-
unsigned int target = coin_control.m_confirm_target ? *coin_control.m_confirm_target : ::nTxConfirmTarget;
60+
unsigned int target = coin_control.m_confirm_target ? *coin_control.m_confirm_target : wallet.m_confirm_target;
6161
// By default estimates are economical iff we are signaling opt-in-RBF
62-
bool conservative_estimate = !coin_control.signalRbf;
62+
bool conservative_estimate = !coin_control.m_signal_bip125_rbf.get_value_or(wallet.m_signal_rbf);
6363
// Allow to override the default fee estimate mode over the CoinControl instance
6464
if (coin_control.m_fee_mode == FeeEstimateMode::CONSERVATIVE) conservative_estimate = true;
6565
else if (coin_control.m_fee_mode == FeeEstimateMode::ECONOMICAL) conservative_estimate = false;
6666

6767
feerate_needed = estimator.estimateSmartFee(target, feeCalc, conservative_estimate);
6868
if (feerate_needed == CFeeRate(0)) {
69-
// if we don't have enough data for estimateSmartFee, then use fallbackFee
70-
feerate_needed = CWallet::fallbackFee;
69+
// if we don't have enough data for estimateSmartFee, then use fallback fee
70+
feerate_needed = wallet.m_fallback_fee;
7171
if (feeCalc) feeCalc->reason = FeeReason::FALLBACK;
7272

7373
// directly return if fallback fee is disabled (feerate 0 == disabled)
74-
if (CWallet::fallbackFee == CFeeRate(0)) return feerate_needed;
74+
if (wallet.m_fallback_fee == CFeeRate(0)) return feerate_needed;
7575
}
7676
// Obey mempool min fee when using smart fee estimation
7777
CFeeRate min_mempool_feerate = pool.GetMinFee(gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000);
@@ -81,21 +81,21 @@ CFeeRate GetMinimumFeeRate(const CCoinControl& coin_control, const CTxMemPool& p
8181
}
8282
}
8383

84-
// prevent user from paying a fee below minRelayTxFee or minTxFee
85-
CFeeRate required_feerate = GetRequiredFeeRate();
84+
// prevent user from paying a fee below the required fee rate
85+
CFeeRate required_feerate = GetRequiredFeeRate(wallet);
8686
if (required_feerate > feerate_needed) {
8787
feerate_needed = required_feerate;
8888
if (feeCalc) feeCalc->reason = FeeReason::REQUIRED;
8989
}
9090
return feerate_needed;
9191
}
9292

93-
CFeeRate GetDiscardRate(const CBlockPolicyEstimator& estimator)
93+
CFeeRate GetDiscardRate(const CWallet& wallet, const CBlockPolicyEstimator& estimator)
9494
{
9595
unsigned int highest_target = estimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
9696
CFeeRate discard_rate = estimator.estimateSmartFee(highest_target, nullptr /* FeeCalculation */, false /* conservative */);
9797
// Don't let discard_rate be greater than longest possible fee estimate if we get a valid fee estimate
98-
discard_rate = (discard_rate == CFeeRate(0)) ? CWallet::m_discard_rate : std::min(discard_rate, CWallet::m_discard_rate);
98+
discard_rate = (discard_rate == CFeeRate(0)) ? wallet.m_discard_rate : std::min(discard_rate, wallet.m_discard_rate);
9999
// Discard rate must be at least dustRelayFee
100100
discard_rate = std::max(discard_rate, ::dustRelayFee);
101101
return discard_rate;

0 commit comments

Comments
 (0)