Skip to content

Commit

Permalink
Merge #10976: [MOVEONLY] Move some static functions out of wallet.h/cpp
Browse files Browse the repository at this point in the history
f01103c MOVEONLY: Init functions wallet/wallet.cpp -> wallet/init.cpp (Russell Yanofsky)
e7fe320 MOVEONLY: Fee functions wallet/wallet.cpp -> wallet/fees.cpp (Russell Yanofsky)
d97fe20 Move some static functions out of wallet.h/cpp (Russell Yanofsky)

Pull request description:

  This just moves some static wallet fee and init functions out of `wallet/wallet.cpp` and into new `wallet/fees.cpp` and `wallet/init.cpp` source files. There is one commit updating declarations and callers, followed by two MOVEONLY commits actually moving the function bodies.

  This change is desirable because wallet.h/cpp are monolithic and hard to navigate, so pulling things out and grouping together pieces of related functionality should improve the organization.

  Another motivation is the wallet process separation work in #10973, where (at least initially) parameter parsing and fee estimation are still done in the main process rather than the wallet process, and having functions that run in different processes scrambled up throughout wallet.cpp is unnecessarily confusing.

Tree-SHA512: 6e6982ff82b2ab4e681c043907e2b1801ceb9513394730070f16c46ad338278a863f5b3759aa13db76a259b268b1c919c81f4e339f0796a3cfb990161e8c316d
  • Loading branch information
laanwj committed Aug 25, 2017
2 parents 3f726c9 + f01103c commit 07c92b9
Show file tree
Hide file tree
Showing 13 changed files with 418 additions and 351 deletions.
4 changes: 4 additions & 0 deletions src/Makefile.am
Expand Up @@ -162,6 +162,8 @@ BITCOIN_CORE_H = \
wallet/crypter.h \
wallet/db.h \
wallet/feebumper.h \
wallet/fees.h \
wallet/init.h \
wallet/rpcwallet.h \
wallet/wallet.h \
wallet/walletdb.h \
Expand Down Expand Up @@ -239,6 +241,8 @@ libbitcoin_wallet_a_SOURCES = \
wallet/crypter.cpp \
wallet/db.cpp \
wallet/feebumper.cpp \
wallet/fees.cpp \
wallet/init.cpp \
wallet/rpcdump.cpp \
wallet/rpcwallet.cpp \
wallet/wallet.cpp \
Expand Down
11 changes: 6 additions & 5 deletions src/init.cpp
Expand Up @@ -43,6 +43,7 @@
#include "utilmoneystr.h"
#include "validationinterface.h"
#ifdef ENABLE_WALLET
#include "wallet/init.h"
#include "wallet/wallet.h"
#endif
#include "warnings.h"
Expand Down Expand Up @@ -420,7 +421,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-maxuploadtarget=<n>", strprintf(_("Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)"), DEFAULT_MAX_UPLOAD_TARGET));

#ifdef ENABLE_WALLET
strUsage += CWallet::GetWalletHelpString(showDebug);
strUsage += GetWalletHelpString(showDebug);
#endif

#if ENABLE_ZMQ
Expand Down Expand Up @@ -1035,7 +1036,7 @@ bool AppInitParameterInteraction()
if (!ParseMoney(gArgs.GetArg("-minrelaytxfee", ""), n)) {
return InitError(AmountErrMsg("minrelaytxfee", gArgs.GetArg("-minrelaytxfee", "")));
}
// High fee check is done afterward in CWallet::ParameterInteraction()
// High fee check is done afterward in WalletParameterInteraction()
::minRelayTxFee = CFeeRate(n);
} else if (incrementalRelayFee > ::minRelayTxFee) {
// Allow only setting incrementalRelayFee to control both
Expand Down Expand Up @@ -1068,7 +1069,7 @@ bool AppInitParameterInteraction()
nBytesPerSigOp = gArgs.GetArg("-bytespersigop", nBytesPerSigOp);

#ifdef ENABLE_WALLET
if (!CWallet::ParameterInteraction())
if (!WalletParameterInteraction())
return false;
#endif

Expand Down Expand Up @@ -1245,7 +1246,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)

// ********************************************************* Step 5: verify wallet database integrity
#ifdef ENABLE_WALLET
if (!CWallet::Verify())
if (!WalletVerify())
return false;
#endif
// ********************************************************* Step 6: network initialization
Expand Down Expand Up @@ -1566,7 +1567,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)

// ********************************************************* Step 8: load wallet
#ifdef ENABLE_WALLET
if (!CWallet::InitLoadWallet())
if (!InitLoadWallet())
return false;
#else
LogPrintf("No wallet support compiled in!\n");
Expand Down
3 changes: 2 additions & 1 deletion src/qt/coincontroldialog.cpp
Expand Up @@ -18,6 +18,7 @@
#include "policy/fees.h"
#include "policy/policy.h"
#include "validation.h" // For mempool
#include "wallet/fees.h"
#include "wallet/wallet.h"

#include <QApplication>
Expand Down Expand Up @@ -510,7 +511,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
nBytes -= 34;

// Fee
nPayFee = CWallet::GetMinimumFee(nBytes, *coinControl, ::mempool, ::feeEstimator, nullptr /* FeeCalculation */);
nPayFee = GetMinimumFee(nBytes, *coinControl, ::mempool, ::feeEstimator, nullptr /* FeeCalculation */);

if (nPayAmount > 0)
{
Expand Down
4 changes: 0 additions & 4 deletions src/qt/optionsdialog.cpp
Expand Up @@ -17,10 +17,6 @@
#include "netbase.h"
#include "txdb.h" // for -dbcache defaults

#ifdef ENABLE_WALLET
#include "wallet/wallet.h" // for CWallet::GetRequiredFee()
#endif

#include <QDataWidgetMapper>
#include <QDir>
#include <QIntValidator>
Expand Down
10 changes: 5 additions & 5 deletions src/qt/sendcoinsdialog.cpp
Expand Up @@ -22,7 +22,7 @@
#include "ui_interface.h"
#include "txmempool.h"
#include "policy/fees.h"
#include "wallet/wallet.h"
#include "wallet/fees.h"

#include <QFontMetrics>
#include <QMessageBox>
Expand Down Expand Up @@ -185,7 +185,7 @@ void SendCoinsDialog::setModel(WalletModel *_model)
connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(coinControlUpdateLabels()));
connect(ui->optInRBF, SIGNAL(stateChanged(int)), this, SLOT(updateSmartFeeLabel()));
connect(ui->optInRBF, SIGNAL(stateChanged(int)), this, SLOT(coinControlUpdateLabels()));
ui->customFee->setSingleStep(CWallet::GetRequiredFee(1000));
ui->customFee->setSingleStep(GetRequiredFee(1000));
updateFeeSectionControls();
updateMinFeeLabel();
updateSmartFeeLabel();
Expand Down Expand Up @@ -610,7 +610,7 @@ void SendCoinsDialog::on_buttonMinimizeFee_clicked()
void SendCoinsDialog::setMinimumFee()
{
ui->radioCustomPerKilobyte->setChecked(true);
ui->customFee->setValue(CWallet::GetRequiredFee(1000));
ui->customFee->setValue(GetRequiredFee(1000));
}

void SendCoinsDialog::updateFeeSectionControls()
Expand Down Expand Up @@ -643,7 +643,7 @@ void SendCoinsDialog::updateMinFeeLabel()
{
if (model && model->getOptionsModel())
ui->checkBoxMinimumFee->setText(tr("Pay only the required fee of %1").arg(
BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), CWallet::GetRequiredFee(1000)) + "/kB")
BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), GetRequiredFee(1000)) + "/kB")
);
}

Expand All @@ -668,7 +668,7 @@ void SendCoinsDialog::updateSmartFeeLabel()
updateCoinControlState(coin_control);
coin_control.m_feerate.reset(); // Explicitly use only fee estimation rate for smart fee labels
FeeCalculation feeCalc;
CFeeRate feeRate = CFeeRate(CWallet::GetMinimumFee(1000, coin_control, ::mempool, ::feeEstimator, &feeCalc));
CFeeRate feeRate = CFeeRate(GetMinimumFee(1000, coin_control, ::mempool, ::feeEstimator, &feeCalc));

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

Expand Down
5 changes: 3 additions & 2 deletions src/wallet/feebumper.cpp
Expand Up @@ -5,6 +5,7 @@
#include "consensus/validation.h"
#include "wallet/coincontrol.h"
#include "wallet/feebumper.h"
#include "wallet/fees.h"
#include "wallet/wallet.h"
#include "policy/fees.h"
#include "policy/policy.h"
Expand Down Expand Up @@ -156,7 +157,7 @@ CFeeBumper::CFeeBumper(const CWallet *pWallet, const uint256 txidIn, const CCoin
currentResult = BumpFeeResult::INVALID_PARAMETER;
return;
}
CAmount requiredFee = CWallet::GetRequiredFee(maxNewTxSize);
CAmount requiredFee = GetRequiredFee(maxNewTxSize);
if (totalFee < requiredFee) {
vErrors.push_back(strprintf("Insufficient totalFee (cannot be less than required fee %s)",
FormatMoney(requiredFee)));
Expand All @@ -166,7 +167,7 @@ CFeeBumper::CFeeBumper(const CWallet *pWallet, const uint256 txidIn, const CCoin
nNewFee = totalFee;
nNewFeeRate = CFeeRate(totalFee, maxNewTxSize);
} else {
nNewFee = CWallet::GetMinimumFee(maxNewTxSize, coin_control, mempool, ::feeEstimator, nullptr /* FeeCalculation */);
nNewFee = GetMinimumFee(maxNewTxSize, coin_control, mempool, ::feeEstimator, nullptr /* FeeCalculation */);
nNewFeeRate = CFeeRate(nNewFee, maxNewTxSize);

// New fee rate must be at least old rate + minimum incremental relay rate
Expand Down
89 changes: 89 additions & 0 deletions src/wallet/fees.cpp
@@ -0,0 +1,89 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "wallet/fees.h"

#include "policy/policy.h"
#include "txmempool.h"
#include "util.h"
#include "validation.h"
#include "wallet/coincontrol.h"
#include "wallet/wallet.h"


CAmount GetRequiredFee(unsigned int nTxBytes)
{
return std::max(CWallet::minTxFee.GetFee(nTxBytes), ::minRelayTxFee.GetFee(nTxBytes));
}


CAmount GetMinimumFee(unsigned int nTxBytes, const CCoinControl& coin_control, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation *feeCalc)
{
/* User control of how to calculate fee uses the following parameter precedence:
1. coin_control.m_feerate
2. coin_control.m_confirm_target
3. payTxFee (user-set global variable)
4. nTxConfirmTarget (user-set global variable)
The first parameter that is set is used.
*/
CAmount fee_needed;
if (coin_control.m_feerate) { // 1.
fee_needed = coin_control.m_feerate->GetFee(nTxBytes);
if (feeCalc) feeCalc->reason = FeeReason::PAYTXFEE;
// Allow to override automatic min/max check over coin control instance
if (coin_control.fOverrideFeeRate) return fee_needed;
}
else if (!coin_control.m_confirm_target && ::payTxFee != CFeeRate(0)) { // 3. TODO: remove magic value of 0 for global payTxFee
fee_needed = ::payTxFee.GetFee(nTxBytes);
if (feeCalc) feeCalc->reason = FeeReason::PAYTXFEE;
}
else { // 2. or 4.
// We will use smart fee estimation
unsigned int target = coin_control.m_confirm_target ? *coin_control.m_confirm_target : ::nTxConfirmTarget;
// By default estimates are economical iff we are signaling opt-in-RBF
bool conservative_estimate = !coin_control.signalRbf;
// Allow to override the default fee estimate mode over the CoinControl instance
if (coin_control.m_fee_mode == FeeEstimateMode::CONSERVATIVE) conservative_estimate = true;
else if (coin_control.m_fee_mode == FeeEstimateMode::ECONOMICAL) conservative_estimate = false;

fee_needed = estimator.estimateSmartFee(target, feeCalc, conservative_estimate).GetFee(nTxBytes);
if (fee_needed == 0) {
// if we don't have enough data for estimateSmartFee, then use fallbackFee
fee_needed = CWallet::fallbackFee.GetFee(nTxBytes);
if (feeCalc) feeCalc->reason = FeeReason::FALLBACK;
}
// Obey mempool min fee when using smart fee estimation
CAmount min_mempool_fee = pool.GetMinFee(gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFee(nTxBytes);
if (fee_needed < min_mempool_fee) {
fee_needed = min_mempool_fee;
if (feeCalc) feeCalc->reason = FeeReason::MEMPOOL_MIN;
}
}

// prevent user from paying a fee below minRelayTxFee or minTxFee
CAmount required_fee = GetRequiredFee(nTxBytes);
if (required_fee > fee_needed) {
fee_needed = required_fee;
if (feeCalc) feeCalc->reason = FeeReason::REQUIRED;
}
// But always obey the maximum
if (fee_needed > maxTxFee) {
fee_needed = maxTxFee;
if (feeCalc) feeCalc->reason = FeeReason::MAXTXFEE;
}
return fee_needed;
}


CFeeRate GetDiscardRate(const CBlockPolicyEstimator& estimator)
{
unsigned int highest_target = estimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
CFeeRate discard_rate = estimator.estimateSmartFee(highest_target, nullptr /* FeeCalculation */, false /* conservative */);
// Don't let discard_rate be greater than longest possible fee estimate if we get a valid fee estimate
discard_rate = (discard_rate == CFeeRate(0)) ? CWallet::m_discard_rate : std::min(discard_rate, CWallet::m_discard_rate);
// Discard rate must be at least dustRelayFee
discard_rate = std::max(discard_rate, ::dustRelayFee);
return discard_rate;
}
34 changes: 34 additions & 0 deletions src/wallet/fees.h
@@ -0,0 +1,34 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_WALLET_FEES_H
#define BITCOIN_WALLET_FEES_H

#include "amount.h"

class CBlockPolicyEstimator;
class CCoinControl;
class CFeeRate;
class CTxMemPool;
struct FeeCalculation;

/**
* Return the minimum required fee taking into account the
* floating relay fee and user set minimum transaction fee
*/
CAmount GetRequiredFee(unsigned int nTxBytes);

/**
* Estimate the minimum fee considering user set parameters
* and the required fee
*/
CAmount GetMinimumFee(unsigned int nTxBytes, const CCoinControl& coin_control, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation *feeCalc);

/**
* Return the maximum feerate for discarding change.
*/
CFeeRate GetDiscardRate(const CBlockPolicyEstimator& estimator);

#endif // BITCOIN_WALLET_FEES_H

0 comments on commit 07c92b9

Please sign in to comment.