aboutsummaryrefslogtreecommitdiff
path: root/src/wallet
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2018-04-24 16:11:02 +0200
committerWladimir J. van der Laan <laanwj@gmail.com>2018-04-24 16:37:30 +0200
commit476cb35551f559573c81a3927856b3f76aecd6e9 (patch)
tree86a663c18bf352bc2998827d1d1d703c949de68b /src/wallet
parentd1d54ae6a362f0761e0a7c35036b6a28d9fab457 (diff)
parentfac0db0ff8e72ca30a0da8a64fc1d115dd2d6f8c (diff)
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
Diffstat (limited to 'src/wallet')
-rw-r--r--src/wallet/coincontrol.h8
-rw-r--r--src/wallet/feebumper.cpp8
-rw-r--r--src/wallet/fees.cpp42
-rw-r--r--src/wallet/fees.h17
-rw-r--r--src/wallet/init.cpp54
-rw-r--r--src/wallet/rpcwallet.cpp22
-rw-r--r--src/wallet/wallet.cpp109
-rw-r--r--src/wallet/wallet.h29
8 files changed, 139 insertions, 150 deletions
diff --git a/src/wallet/coincontrol.h b/src/wallet/coincontrol.h
index 52d6a291c9..2f08162ee4 100644
--- a/src/wallet/coincontrol.h
+++ b/src/wallet/coincontrol.h
@@ -26,12 +26,12 @@ public:
bool fAllowWatchOnly;
//! Override automatic min/max checks on fee, m_feerate must be set if true
bool fOverrideFeeRate;
- //! Override the default payTxFee if set
+ //! Override the wallet's m_pay_tx_fee if set
boost::optional<CFeeRate> m_feerate;
//! Override the default confirmation target if set
boost::optional<unsigned int> m_confirm_target;
- //! Signal BIP-125 replace by fee.
- bool signalRbf;
+ //! Override the wallet's m_signal_rbf if set
+ boost::optional<bool> m_signal_bip125_rbf;
//! Fee estimation mode to control arguments to estimateSmartFee
FeeEstimateMode m_fee_mode;
@@ -50,7 +50,7 @@ public:
m_feerate.reset();
fOverrideFeeRate = false;
m_confirm_target.reset();
- signalRbf = fWalletRbf;
+ m_signal_bip125_rbf.reset();
m_fee_mode = FeeEstimateMode::UNSET;
}
diff --git a/src/wallet/feebumper.cpp b/src/wallet/feebumper.cpp
index 5c34b39ec8..4d70dde72a 100644
--- a/src/wallet/feebumper.cpp
+++ b/src/wallet/feebumper.cpp
@@ -134,7 +134,7 @@ Result CreateTransaction(const CWallet* wallet, const uint256& txid, const CCoin
FormatMoney(minTotalFee), FormatMoney(nOldFeeRate.GetFee(maxNewTxSize)), FormatMoney(::incrementalRelayFee.GetFee(maxNewTxSize))));
return Result::INVALID_PARAMETER;
}
- CAmount requiredFee = GetRequiredFee(maxNewTxSize);
+ CAmount requiredFee = GetRequiredFee(*wallet, maxNewTxSize);
if (total_fee < requiredFee) {
errors.push_back(strprintf("Insufficient totalFee (cannot be less than required fee %s)",
FormatMoney(requiredFee)));
@@ -143,7 +143,7 @@ Result CreateTransaction(const CWallet* wallet, const uint256& txid, const CCoin
new_fee = total_fee;
nNewFeeRate = CFeeRate(total_fee, maxNewTxSize);
} else {
- new_fee = GetMinimumFee(maxNewTxSize, coin_control, mempool, ::feeEstimator, nullptr /* FeeCalculation */);
+ new_fee = GetMinimumFee(*wallet, maxNewTxSize, coin_control, mempool, ::feeEstimator, nullptr /* FeeCalculation */);
nNewFeeRate = CFeeRate(new_fee, maxNewTxSize);
// 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
// If the output would become dust, discard it (converting the dust to fee)
poutput->nValue -= nDelta;
- if (poutput->nValue <= GetDustThreshold(*poutput, GetDiscardRate(::feeEstimator))) {
+ if (poutput->nValue <= GetDustThreshold(*poutput, GetDiscardRate(*wallet, ::feeEstimator))) {
LogPrint(BCLog::RPC, "Bumping fee and discarding dust output\n");
new_fee += poutput->nValue;
mtx.vout.erase(mtx.vout.begin() + nOutput);
}
// Mark new tx not replaceable, if requested.
- if (!coin_control.signalRbf) {
+ if (!coin_control.m_signal_bip125_rbf.get_value_or(wallet->m_signal_rbf)) {
for (auto& input : mtx.vin) {
if (input.nSequence < 0xfffffffe) input.nSequence = 0xfffffffe;
}
diff --git a/src/wallet/fees.cpp b/src/wallet/fees.cpp
index 03c32d3b97..8d576a6689 100644
--- a/src/wallet/fees.cpp
+++ b/src/wallet/fees.cpp
@@ -13,15 +13,15 @@
#include <wallet/wallet.h>
-CAmount GetRequiredFee(unsigned int nTxBytes)
+CAmount GetRequiredFee(const CWallet& wallet, unsigned int nTxBytes)
{
- return std::max(CWallet::minTxFee.GetFee(nTxBytes), ::minRelayTxFee.GetFee(nTxBytes));
+ return GetRequiredFeeRate(wallet).GetFee(nTxBytes);
}
-CAmount GetMinimumFee(unsigned int nTxBytes, const CCoinControl& coin_control, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation *feeCalc)
+CAmount GetMinimumFee(const CWallet& wallet, unsigned int nTxBytes, const CCoinControl& coin_control, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation* feeCalc)
{
- CAmount fee_needed = GetMinimumFeeRate(coin_control, pool, estimator, feeCalc).GetFee(nTxBytes);
+ CAmount fee_needed = GetMinimumFeeRate(wallet, coin_control, pool, estimator, feeCalc).GetFee(nTxBytes);
// Always obey the maximum
if (fee_needed > maxTxFee) {
fee_needed = maxTxFee;
@@ -30,48 +30,48 @@ CAmount GetMinimumFee(unsigned int nTxBytes, const CCoinControl& coin_control, c
return fee_needed;
}
-CFeeRate GetRequiredFeeRate()
+CFeeRate GetRequiredFeeRate(const CWallet& wallet)
{
- return std::max(CWallet::minTxFee, ::minRelayTxFee);
+ return std::max(wallet.m_min_fee, ::minRelayTxFee);
}
-CFeeRate GetMinimumFeeRate(const CCoinControl& coin_control, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation *feeCalc)
+CFeeRate GetMinimumFeeRate(const CWallet& wallet, 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)
+ 3. m_pay_tx_fee (user-set member variable of wallet)
+ 4. m_confirm_target (user-set member variable of wallet)
The first parameter that is set is used.
*/
- CFeeRate feerate_needed ;
+ CFeeRate feerate_needed;
if (coin_control.m_feerate) { // 1.
feerate_needed = *(coin_control.m_feerate);
if (feeCalc) feeCalc->reason = FeeReason::PAYTXFEE;
// Allow to override automatic min/max check over coin control instance
if (coin_control.fOverrideFeeRate) return feerate_needed;
}
- else if (!coin_control.m_confirm_target && ::payTxFee != CFeeRate(0)) { // 3. TODO: remove magic value of 0 for global payTxFee
- feerate_needed = ::payTxFee;
+ 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
+ feerate_needed = wallet.m_pay_tx_fee;
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;
+ unsigned int target = coin_control.m_confirm_target ? *coin_control.m_confirm_target : wallet.m_confirm_target;
// By default estimates are economical iff we are signaling opt-in-RBF
- bool conservative_estimate = !coin_control.signalRbf;
+ bool conservative_estimate = !coin_control.m_signal_bip125_rbf.get_value_or(wallet.m_signal_rbf);
// 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;
feerate_needed = estimator.estimateSmartFee(target, feeCalc, conservative_estimate);
if (feerate_needed == CFeeRate(0)) {
- // if we don't have enough data for estimateSmartFee, then use fallbackFee
- feerate_needed = CWallet::fallbackFee;
+ // if we don't have enough data for estimateSmartFee, then use fallback fee
+ feerate_needed = wallet.m_fallback_fee;
if (feeCalc) feeCalc->reason = FeeReason::FALLBACK;
// directly return if fallback fee is disabled (feerate 0 == disabled)
- if (CWallet::fallbackFee == CFeeRate(0)) return feerate_needed;
+ if (wallet.m_fallback_fee == CFeeRate(0)) return feerate_needed;
}
// Obey mempool min fee when using smart fee estimation
CFeeRate min_mempool_feerate = pool.GetMinFee(gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000);
@@ -81,8 +81,8 @@ CFeeRate GetMinimumFeeRate(const CCoinControl& coin_control, const CTxMemPool& p
}
}
- // prevent user from paying a fee below minRelayTxFee or minTxFee
- CFeeRate required_feerate = GetRequiredFeeRate();
+ // prevent user from paying a fee below the required fee rate
+ CFeeRate required_feerate = GetRequiredFeeRate(wallet);
if (required_feerate > feerate_needed) {
feerate_needed = required_feerate;
if (feeCalc) feeCalc->reason = FeeReason::REQUIRED;
@@ -90,12 +90,12 @@ CFeeRate GetMinimumFeeRate(const CCoinControl& coin_control, const CTxMemPool& p
return feerate_needed;
}
-CFeeRate GetDiscardRate(const CBlockPolicyEstimator& estimator)
+CFeeRate GetDiscardRate(const CWallet& wallet, 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 = (discard_rate == CFeeRate(0)) ? wallet.m_discard_rate : std::min(discard_rate, wallet.m_discard_rate);
// Discard rate must be at least dustRelayFee
discard_rate = std::max(discard_rate, ::dustRelayFee);
return discard_rate;
diff --git a/src/wallet/fees.h b/src/wallet/fees.h
index a627af70b0..b3cd064abc 100644
--- a/src/wallet/fees.h
+++ b/src/wallet/fees.h
@@ -12,35 +12,36 @@ class CBlockPolicyEstimator;
class CCoinControl;
class CFeeRate;
class CTxMemPool;
+class CWallet;
struct FeeCalculation;
/**
- * Return the minimum required fee taking into account the
- * floating relay fee and user set minimum transaction fee
+ * Return the minimum required absolute fee for this size
+ * based on the required fee rate
*/
-CAmount GetRequiredFee(unsigned int nTxBytes);
+CAmount GetRequiredFee(const CWallet& wallet, 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);
+CAmount GetMinimumFee(const CWallet& wallet, unsigned int nTxBytes, const CCoinControl& coin_control, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation* feeCalc);
/**
* Return the minimum required feerate taking into account the
- * floating relay feerate and user set minimum transaction feerate
+ * minimum relay feerate and user set minimum transaction feerate
*/
-CFeeRate GetRequiredFeeRate();
+CFeeRate GetRequiredFeeRate(const CWallet& wallet);
/**
* Estimate the minimum fee rate considering user set parameters
* and the required fee
*/
-CFeeRate GetMinimumFeeRate(const CCoinControl& coin_control, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation *feeCalc);
+CFeeRate GetMinimumFeeRate(const CWallet& wallet, const CCoinControl& coin_control, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation* feeCalc);
/**
* Return the maximum feerate for discarding change.
*/
-CFeeRate GetDiscardRate(const CBlockPolicyEstimator& estimator);
+CFeeRate GetDiscardRate(const CWallet& wallet, const CBlockPolicyEstimator& estimator);
#endif // BITCOIN_WALLET_FEES_H
diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp
index 5091477dfd..06f9c730c0 100644
--- a/src/wallet/init.cpp
+++ b/src/wallet/init.cpp
@@ -64,7 +64,7 @@ std::string WalletInit::GetHelpString(bool showDebug) const
strUsage += HelpMessageOpt("-mintxfee=<amt>", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)"),
CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MINFEE)));
strUsage += HelpMessageOpt("-paytxfee=<amt>", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"),
- CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK())));
+ CURRENCY_UNIT, FormatMoney(CFeeRate{DEFAULT_PAY_TX_FEE}.GetFeePerK())));
strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions on startup"));
strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet on startup"));
strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE));
@@ -149,55 +149,6 @@ bool WalletInit::ParameterInteraction() const
InitWarning(AmountHighWarn("-minrelaytxfee") + " " +
_("The wallet will avoid paying less than the minimum relay fee."));
- if (gArgs.IsArgSet("-mintxfee"))
- {
- CAmount n = 0;
- if (!ParseMoney(gArgs.GetArg("-mintxfee", ""), n) || 0 == n)
- return InitError(AmountErrMsg("mintxfee", gArgs.GetArg("-mintxfee", "")));
- if (n > HIGH_TX_FEE_PER_KB)
- InitWarning(AmountHighWarn("-mintxfee") + " " +
- _("This is the minimum transaction fee you pay on every transaction."));
- CWallet::minTxFee = CFeeRate(n);
- }
-
- g_wallet_allow_fallback_fee = Params().IsFallbackFeeEnabled();
- if (gArgs.IsArgSet("-fallbackfee"))
- {
- CAmount nFeePerK = 0;
- if (!ParseMoney(gArgs.GetArg("-fallbackfee", ""), nFeePerK))
- return InitError(strprintf(_("Invalid amount for -fallbackfee=<amount>: '%s'"), gArgs.GetArg("-fallbackfee", "")));
- if (nFeePerK > HIGH_TX_FEE_PER_KB)
- InitWarning(AmountHighWarn("-fallbackfee") + " " +
- _("This is the transaction fee you may pay when fee estimates are not available."));
- CWallet::fallbackFee = CFeeRate(nFeePerK);
- g_wallet_allow_fallback_fee = nFeePerK != 0; //disable fallback fee in case value was set to 0, enable if non-null value
- }
- if (gArgs.IsArgSet("-discardfee"))
- {
- CAmount nFeePerK = 0;
- if (!ParseMoney(gArgs.GetArg("-discardfee", ""), nFeePerK))
- return InitError(strprintf(_("Invalid amount for -discardfee=<amount>: '%s'"), gArgs.GetArg("-discardfee", "")));
- if (nFeePerK > HIGH_TX_FEE_PER_KB)
- InitWarning(AmountHighWarn("-discardfee") + " " +
- _("This is the transaction fee you may discard if change is smaller than dust at this level"));
- CWallet::m_discard_rate = CFeeRate(nFeePerK);
- }
- if (gArgs.IsArgSet("-paytxfee"))
- {
- CAmount nFeePerK = 0;
- if (!ParseMoney(gArgs.GetArg("-paytxfee", ""), nFeePerK))
- return InitError(AmountErrMsg("paytxfee", gArgs.GetArg("-paytxfee", "")));
- if (nFeePerK > HIGH_TX_FEE_PER_KB)
- InitWarning(AmountHighWarn("-paytxfee") + " " +
- _("This is the transaction fee you will pay if you send a transaction."));
-
- payTxFee = CFeeRate(nFeePerK, 1000);
- if (payTxFee < ::minRelayTxFee)
- {
- return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"),
- gArgs.GetArg("-paytxfee", ""), ::minRelayTxFee.ToString()));
- }
- }
if (gArgs.IsArgSet("-maxtxfee"))
{
CAmount nMaxFee = 0;
@@ -212,9 +163,6 @@ bool WalletInit::ParameterInteraction() const
gArgs.GetArg("-maxtxfee", ""), ::minRelayTxFee.ToString()));
}
}
- nTxConfirmTarget = gArgs.GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET);
- bSpendZeroConfChange = gArgs.GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE);
- fWalletRbf = gArgs.GetBoolArg("-walletrbf", DEFAULT_WALLET_RBF);
return true;
}
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index 5bc8788c7c..c4c6701081 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -557,7 +557,7 @@ UniValue sendtoaddress(const JSONRPCRequest& request)
CCoinControl coin_control;
if (!request.params[5].isNull()) {
- coin_control.signalRbf = request.params[5].get_bool();
+ coin_control.m_signal_bip125_rbf = request.params[5].get_bool();
}
if (!request.params[6].isNull()) {
@@ -1201,7 +1201,7 @@ UniValue sendmany(const JSONRPCRequest& request)
CCoinControl coin_control;
if (!request.params[5].isNull()) {
- coin_control.signalRbf = request.params[5].get_bool();
+ coin_control.m_signal_bip125_rbf = request.params[5].get_bool();
}
if (!request.params[6].isNull()) {
@@ -2915,10 +2915,10 @@ UniValue settxfee(const JSONRPCRequest& request)
return NullUniValue;
}
- if (request.fHelp || request.params.size() < 1 || request.params.size() > 1)
+ if (request.fHelp || request.params.size() < 1 || request.params.size() > 1) {
throw std::runtime_error(
"settxfee amount\n"
- "\nSet the transaction fee per kB. Overwrites the paytxfee parameter.\n"
+ "\nSet the transaction fee per kB for this wallet. Overrides the global -paytxfee command line parameter.\n"
"\nArguments:\n"
"1. amount (numeric or string, required) The transaction fee in " + CURRENCY_UNIT + "/kB\n"
"\nResult\n"
@@ -2927,13 +2927,13 @@ UniValue settxfee(const JSONRPCRequest& request)
+ HelpExampleCli("settxfee", "0.00001")
+ HelpExampleRpc("settxfee", "0.00001")
);
+ }
LOCK2(cs_main, pwallet->cs_wallet);
- // Amount
CAmount nAmount = AmountFromValue(request.params[0]);
- payTxFee = CFeeRate(nAmount, 1000);
+ pwallet->m_pay_tx_fee = CFeeRate(nAmount, 1000);
return true;
}
@@ -2994,9 +2994,9 @@ UniValue getwalletinfo(const JSONRPCRequest& request)
if (pwallet->IsCrypted()) {
obj.pushKV("unlocked_until", pwallet->nRelockTime);
}
- obj.pushKV("paytxfee", ValueFromAmount(payTxFee.GetFeePerK()));
+ obj.pushKV("paytxfee", ValueFromAmount(pwallet->m_pay_tx_fee.GetFeePerK()));
if (!masterKeyID.IsNull())
- obj.pushKV("hdmasterkeyid", masterKeyID.GetHex());
+ obj.pushKV("hdmasterkeyid", masterKeyID.GetHex());
return obj;
}
@@ -3377,7 +3377,7 @@ UniValue fundrawtransaction(const JSONRPCRequest& request)
subtractFeeFromOutputs = options["subtractFeeFromOutputs"].get_array();
if (options.exists("replaceable")) {
- coinControl.signalRbf = options["replaceable"].get_bool();
+ coinControl.m_signal_bip125_rbf = options["replaceable"].get_bool();
}
if (options.exists("conf_target")) {
if (options.exists("feeRate")) {
@@ -3566,7 +3566,7 @@ UniValue bumpfee(const JSONRPCRequest& request)
// optional parameters
CAmount totalFee = 0;
CCoinControl coin_control;
- coin_control.signalRbf = true;
+ coin_control.m_signal_bip125_rbf = true;
if (!request.params[1].isNull()) {
UniValue options = request.params[1];
RPCTypeCheckObj(options,
@@ -3590,7 +3590,7 @@ UniValue bumpfee(const JSONRPCRequest& request)
}
if (options.exists("replaceable")) {
- coin_control.signalRbf = options["replaceable"].get_bool();
+ coin_control.m_signal_bip125_rbf = options["replaceable"].get_bool();
}
if (options.exists("estimate_mode")) {
if (!FeeModeFromString(options["estimate_mode"].get_str(), coin_control.m_fee_mode)) {
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 8c392434fc..ad3dd4cd2c 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -72,29 +72,8 @@ CWallet* GetWallet(const std::string& name)
return nullptr;
}
-/** Transaction fee set by the user */
-CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE);
-unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET;
-bool bSpendZeroConfChange = DEFAULT_SPEND_ZEROCONF_CHANGE;
-bool fWalletRbf = DEFAULT_WALLET_RBF;
-bool g_wallet_allow_fallback_fee = true; //<! will be defined via chainparams
-
const uint32_t BIP32_HARDENED_KEY_LIMIT = 0x80000000;
-/**
- * Fees smaller than this (in satoshi) are considered zero fee (for transaction creation)
- * Override with -mintxfee
- */
-CFeeRate CWallet::minTxFee = CFeeRate(DEFAULT_TRANSACTION_MINFEE);
-/**
- * If fee estimation does not have enough data to provide estimates, use this fee instead.
- * Has no effect if not using fee estimation
- * Override with -fallbackfee
- */
-CFeeRate CWallet::fallbackFee = CFeeRate(DEFAULT_FALLBACK_FEE);
-
-CFeeRate CWallet::m_discard_rate = CFeeRate(DEFAULT_DISCARD_FEE);
-
const uint256 CMerkleTx::ABANDON_HASH(uint256S("0000000000000000000000000000000000000000000000000000000000000001"));
/** @defgroup mapWallet
@@ -2054,7 +2033,7 @@ bool CWalletTx::IsTrusted() const
return true;
if (nDepth < 0)
return false;
- if (!bSpendZeroConfChange || !IsFromMe(ISMINE_ALL)) // using wtx's cached debit
+ if (!pwallet->m_spend_zero_conf_change || !IsFromMe(ISMINE_ALL)) // using wtx's cached debit
return false;
// Don't trust unconfirmed transactions from us unless they are in the mempool.
@@ -2490,10 +2469,10 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, const CoinEligibil
FeeCalculation feeCalc;
CCoinControl temp;
temp.m_confirm_target = 1008;
- CFeeRate long_term_feerate = GetMinimumFeeRate(temp, ::mempool, ::feeEstimator, &feeCalc);
+ CFeeRate long_term_feerate = GetMinimumFeeRate(*this, temp, ::mempool, ::feeEstimator, &feeCalc);
// Calculate cost of change
- CAmount cost_of_change = GetDiscardRate(::feeEstimator).GetFee(coin_selection_params.change_spend_size) + coin_selection_params.effective_fee.GetFee(coin_selection_params.change_output_size);
+ CAmount cost_of_change = GetDiscardRate(*this, ::feeEstimator).GetFee(coin_selection_params.change_spend_size) + coin_selection_params.effective_fee.GetFee(coin_selection_params.change_output_size);
// Filter by the min conf specs and add to utxo_pool and calculate effective value
for (const COutput &output : vCoins)
@@ -2590,11 +2569,11 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm
bool res = nTargetValue <= nValueFromPresetInputs ||
SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, CoinEligibilityFilter(1, 6, 0), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used) ||
SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, CoinEligibilityFilter(1, 1, 0), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used) ||
- (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, CoinEligibilityFilter(0, 1, 2), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
- (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, CoinEligibilityFilter(0, 1, std::min((size_t)4, nMaxChainLength/3)), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
- (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, CoinEligibilityFilter(0, 1, nMaxChainLength/2), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
- (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, CoinEligibilityFilter(0, 1, nMaxChainLength), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
- (bSpendZeroConfChange && !fRejectLongChains && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, CoinEligibilityFilter(0, 1, std::numeric_limits<uint64_t>::max()), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used));
+ (m_spend_zero_conf_change && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, CoinEligibilityFilter(0, 1, 2), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
+ (m_spend_zero_conf_change && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, CoinEligibilityFilter(0, 1, std::min((size_t)4, nMaxChainLength/3)), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
+ (m_spend_zero_conf_change && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, CoinEligibilityFilter(0, 1, nMaxChainLength/2), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
+ (m_spend_zero_conf_change && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, CoinEligibilityFilter(0, 1, nMaxChainLength), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
+ (m_spend_zero_conf_change && !fRejectLongChains && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, CoinEligibilityFilter(0, 1, std::numeric_limits<uint64_t>::max()), vCoins, setCoinsRet, nValueRet, coin_selection_params, bnb_used));
// because SelectCoinsMinConf clears the setCoinsRet, we now add the possible inputs to the coinset
setCoinsRet.insert(setPresetCoins.begin(), setPresetCoins.end());
@@ -2813,10 +2792,10 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
CTxOut change_prototype_txout(0, scriptChange);
coin_selection_params.change_output_size = GetSerializeSize(change_prototype_txout, SER_DISK, 0);
- CFeeRate discard_rate = GetDiscardRate(::feeEstimator);
+ CFeeRate discard_rate = GetDiscardRate(*this, ::feeEstimator);
// Get the fee rate to use effective values in coin selection
- CFeeRate nFeeRateNeeded = GetMinimumFeeRate(coin_control, ::mempool, ::feeEstimator, &feeCalc);
+ CFeeRate nFeeRateNeeded = GetMinimumFeeRate(*this, coin_control, ::mempool, ::feeEstimator, &feeCalc);
nFeeRet = 0;
bool pick_new_inputs = true;
@@ -2940,8 +2919,8 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
return false;
}
- nFeeNeeded = GetMinimumFee(nBytes, coin_control, ::mempool, ::feeEstimator, &feeCalc);
- if (feeCalc.reason == FeeReason::FALLBACK && !g_wallet_allow_fallback_fee) {
+ nFeeNeeded = GetMinimumFee(*this, nBytes, coin_control, ::mempool, ::feeEstimator, &feeCalc);
+ if (feeCalc.reason == FeeReason::FALLBACK && !m_allow_fallback_fee) {
// eventually allow a fallback fee
strFailReason = _("Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable -fallbackfee.");
return false;
@@ -2968,7 +2947,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
// change output. Only try this once.
if (nChangePosInOut == -1 && nSubtractFeeFromAmount == 0 && pick_new_inputs) {
unsigned int tx_size_with_change = nBytes + coin_selection_params.change_output_size + 2; // Add 2 as a buffer in case increasing # of outputs changes compact size
- CAmount fee_needed_with_change = GetMinimumFee(tx_size_with_change, coin_control, ::mempool, ::feeEstimator, nullptr);
+ CAmount fee_needed_with_change = GetMinimumFee(*this, tx_size_with_change, coin_control, ::mempool, ::feeEstimator, nullptr);
CAmount minimum_value_for_change = GetDustThreshold(change_prototype_txout, discard_rate);
if (nFeeRet >= fee_needed_with_change + minimum_value_for_change) {
pick_new_inputs = false;
@@ -3035,7 +3014,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
// to avoid conflicting with other possible uses of nSequence,
// and in the spirit of "smallest possible change from prior
// behavior."
- const uint32_t nSequence = coin_control.signalRbf ? MAX_BIP125_RBF_SEQUENCE : (CTxIn::SEQUENCE_FINAL - 1);
+ const uint32_t nSequence = coin_control.m_signal_bip125_rbf.get_value_or(m_signal_rbf) ? MAX_BIP125_RBF_SEQUENCE : (CTxIn::SEQUENCE_FINAL - 1);
for (const auto& coin : selected_coins) {
txNew.vin.push_back(CTxIn(coin.outpoint, CScript(), nSequence));
}
@@ -4080,6 +4059,66 @@ CWallet* CWallet::CreateWalletFromFile(const std::string& name, const fs::path&
return nullptr;
}
+ if (gArgs.IsArgSet("-mintxfee")) {
+ CAmount n = 0;
+ if (!ParseMoney(gArgs.GetArg("-mintxfee", ""), n) || 0 == n) {
+ InitError(AmountErrMsg("mintxfee", gArgs.GetArg("-mintxfee", "")));
+ return nullptr;
+ }
+ if (n > HIGH_TX_FEE_PER_KB) {
+ InitWarning(AmountHighWarn("-mintxfee") + " " +
+ _("This is the minimum transaction fee you pay on every transaction."));
+ }
+ walletInstance->m_min_fee = CFeeRate(n);
+ }
+
+ walletInstance->m_allow_fallback_fee = Params().IsFallbackFeeEnabled();
+ if (gArgs.IsArgSet("-fallbackfee")) {
+ CAmount nFeePerK = 0;
+ if (!ParseMoney(gArgs.GetArg("-fallbackfee", ""), nFeePerK)) {
+ InitError(strprintf(_("Invalid amount for -fallbackfee=<amount>: '%s'"), gArgs.GetArg("-fallbackfee", "")));
+ return nullptr;
+ }
+ if (nFeePerK > HIGH_TX_FEE_PER_KB) {
+ InitWarning(AmountHighWarn("-fallbackfee") + " " +
+ _("This is the transaction fee you may pay when fee estimates are not available."));
+ }
+ walletInstance->m_fallback_fee = CFeeRate(nFeePerK);
+ walletInstance->m_allow_fallback_fee = nFeePerK != 0; //disable fallback fee in case value was set to 0, enable if non-null value
+ }
+ if (gArgs.IsArgSet("-discardfee")) {
+ CAmount nFeePerK = 0;
+ if (!ParseMoney(gArgs.GetArg("-discardfee", ""), nFeePerK)) {
+ InitError(strprintf(_("Invalid amount for -discardfee=<amount>: '%s'"), gArgs.GetArg("-discardfee", "")));
+ return nullptr;
+ }
+ if (nFeePerK > HIGH_TX_FEE_PER_KB) {
+ InitWarning(AmountHighWarn("-discardfee") + " " +
+ _("This is the transaction fee you may discard if change is smaller than dust at this level"));
+ }
+ walletInstance->m_discard_rate = CFeeRate(nFeePerK);
+ }
+ if (gArgs.IsArgSet("-paytxfee")) {
+ CAmount nFeePerK = 0;
+ if (!ParseMoney(gArgs.GetArg("-paytxfee", ""), nFeePerK)) {
+ InitError(AmountErrMsg("paytxfee", gArgs.GetArg("-paytxfee", "")));
+ return nullptr;
+ }
+ if (nFeePerK > HIGH_TX_FEE_PER_KB) {
+ InitWarning(AmountHighWarn("-paytxfee") + " " +
+ _("This is the transaction fee you will pay if you send a transaction."));
+ }
+ walletInstance->m_pay_tx_fee = CFeeRate(nFeePerK, 1000);
+ if (walletInstance->m_pay_tx_fee < ::minRelayTxFee) {
+ InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"),
+ gArgs.GetArg("-paytxfee", ""), ::minRelayTxFee.ToString()));
+ return nullptr;
+ }
+ }
+ walletInstance->m_confirm_target = gArgs.GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET);
+ walletInstance->m_spend_zero_conf_change = gArgs.GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE);
+ walletInstance->m_signal_rbf = gArgs.GetBoolArg("-walletrbf", DEFAULT_WALLET_RBF);
+
LogPrintf(" wallet %15dms\n", GetTimeMillis() - nStart);
// Try to top up keypool. No-op if the wallet is locked.
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index dd165de825..780c82ac36 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -38,22 +38,13 @@ bool HasWallets();
std::vector<CWallet*> GetWallets();
CWallet* GetWallet(const std::string& name);
-/**
- * Settings
- */
-extern CFeeRate payTxFee;
-extern unsigned int nTxConfirmTarget;
-extern bool bSpendZeroConfChange;
-extern bool fWalletRbf;
-extern bool g_wallet_allow_fallback_fee;
-
//! Default for -keypool
static const unsigned int DEFAULT_KEYPOOL_SIZE = 1000;
//! -paytxfee default
-static const CAmount DEFAULT_TRANSACTION_FEE = 0;
+constexpr CAmount DEFAULT_PAY_TX_FEE = 0;
//! -fallbackfee default
static const CAmount DEFAULT_FALLBACK_FEE = 20000;
-//! -m_discard_rate default
+//! -discardfee default
static const CAmount DEFAULT_DISCARD_FEE = 10000;
//! -mintxfee default
static const CAmount DEFAULT_TRANSACTION_MINFEE = 1000;
@@ -968,9 +959,19 @@ public:
bool DummySignTx(CMutableTransaction &txNew, const std::vector<CTxOut> &txouts) const;
bool DummySignInput(CTxIn &tx_in, const CTxOut &txout) const;
- static CFeeRate minTxFee;
- static CFeeRate fallbackFee;
- static CFeeRate m_discard_rate;
+ CFeeRate m_pay_tx_fee{DEFAULT_PAY_TX_FEE};
+ unsigned int m_confirm_target{DEFAULT_TX_CONFIRM_TARGET};
+ bool m_spend_zero_conf_change{DEFAULT_SPEND_ZEROCONF_CHANGE};
+ bool m_signal_rbf{DEFAULT_WALLET_RBF};
+ bool m_allow_fallback_fee{true}; //<! will be defined via chainparams
+ CFeeRate m_min_fee{DEFAULT_TRANSACTION_MINFEE}; //!< Override with -mintxfee
+ /**
+ * If fee estimation does not have enough data to provide estimates, use this fee instead.
+ * Has no effect if not using fee estimation
+ * Override with -fallbackfee
+ */
+ CFeeRate m_fallback_fee{DEFAULT_FALLBACK_FEE};
+ CFeeRate m_discard_rate{DEFAULT_DISCARD_FEE};
OutputType m_default_address_type{DEFAULT_ADDRESS_TYPE};
OutputType m_default_change_type{OutputType::NONE}; // Default to OutputType::NONE if not set by -changetype