Remove uses of fee globals in wallet code
This commit does not change behavior.
This commit is contained in:
parent
1fb0a4a04e
commit
cc02c796d3
12 changed files with 54 additions and 36 deletions
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include <chain.h>
|
||||
#include <chainparams.h>
|
||||
#include <policy/fees.h>
|
||||
#include <policy/policy.h>
|
||||
#include <policy/rbf.h>
|
||||
#include <primitives/block.h>
|
||||
#include <sync.h>
|
||||
|
@ -214,6 +216,18 @@ public:
|
|||
return ::mempool.CalculateMemPoolAncestors(entry, ancestors, limit_ancestor_count, limit_ancestor_size,
|
||||
limit_descendant_count, limit_descendant_size, unused_error_string);
|
||||
}
|
||||
CFeeRate estimateSmartFee(int num_blocks, bool conservative, FeeCalculation* calc) override
|
||||
{
|
||||
return ::feeEstimator.estimateSmartFee(num_blocks, calc, conservative);
|
||||
}
|
||||
unsigned int estimateMaxBlocks() override
|
||||
{
|
||||
return ::feeEstimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
|
||||
}
|
||||
CFeeRate mempoolMinFee() override
|
||||
{
|
||||
return ::mempool.GetMinFee(gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -19,6 +19,7 @@ class CScheduler;
|
|||
class CTransaction;
|
||||
class uint256;
|
||||
struct CBlockLocator;
|
||||
struct FeeCalculation;
|
||||
|
||||
namespace interfaces {
|
||||
|
||||
|
@ -145,6 +146,15 @@ public:
|
|||
|
||||
//! Check chain limits.
|
||||
virtual bool checkChainLimits(CTransactionRef tx) = 0;
|
||||
|
||||
//! Estimate smart fee.
|
||||
virtual CFeeRate estimateSmartFee(int num_blocks, bool conservative, FeeCalculation* calc = nullptr) = 0;
|
||||
|
||||
//! Fee estimator max target.
|
||||
virtual unsigned int estimateMaxBlocks() = 0;
|
||||
|
||||
//! Pool min fee.
|
||||
virtual CFeeRate mempoolMinFee() = 0;
|
||||
};
|
||||
|
||||
//! Interface to let node manage chain clients (wallets, or maybe tools for
|
||||
|
|
|
@ -457,7 +457,7 @@ public:
|
|||
{
|
||||
FeeCalculation fee_calc;
|
||||
CAmount result;
|
||||
result = GetMinimumFee(*m_wallet, tx_bytes, coin_control, ::mempool, ::feeEstimator, &fee_calc);
|
||||
result = GetMinimumFee(*m_wallet, tx_bytes, coin_control, &fee_calc);
|
||||
if (returned_target) *returned_target = fee_calc.returnedTarget;
|
||||
if (reason) *reason = fee_calc.reason;
|
||||
return result;
|
||||
|
|
|
@ -843,7 +843,8 @@ static UniValue estimatesmartfee(const JSONRPCRequest& request)
|
|||
|
||||
RPCTypeCheck(request.params, {UniValue::VNUM, UniValue::VSTR});
|
||||
RPCTypeCheckArgument(request.params[0], UniValue::VNUM);
|
||||
unsigned int conf_target = ParseConfirmTarget(request.params[0]);
|
||||
unsigned int max_target = ::feeEstimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
|
||||
unsigned int conf_target = ParseConfirmTarget(request.params[0], max_target);
|
||||
bool conservative = true;
|
||||
if (!request.params[1].isNull()) {
|
||||
FeeEstimateMode fee_mode;
|
||||
|
@ -915,7 +916,8 @@ static UniValue estimaterawfee(const JSONRPCRequest& request)
|
|||
|
||||
RPCTypeCheck(request.params, {UniValue::VNUM, UniValue::VNUM}, true);
|
||||
RPCTypeCheckArgument(request.params[0], UniValue::VNUM);
|
||||
unsigned int conf_target = ParseConfirmTarget(request.params[0]);
|
||||
unsigned int max_target = ::feeEstimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
|
||||
unsigned int conf_target = ParseConfirmTarget(request.params[0], max_target);
|
||||
double threshold = 0.95;
|
||||
if (!request.params[1].isNull()) {
|
||||
threshold = request.params[1].get_real();
|
||||
|
|
|
@ -4,11 +4,9 @@
|
|||
|
||||
#include <key_io.h>
|
||||
#include <keystore.h>
|
||||
#include <policy/fees.h>
|
||||
#include <rpc/util.h>
|
||||
#include <tinyformat.h>
|
||||
#include <util/strencodings.h>
|
||||
#include <validation.h>
|
||||
|
||||
InitInterfaces* g_rpc_interfaces = nullptr;
|
||||
|
||||
|
@ -130,10 +128,9 @@ UniValue DescribeAddress(const CTxDestination& dest)
|
|||
return boost::apply_visitor(DescribeAddressVisitor(), dest);
|
||||
}
|
||||
|
||||
unsigned int ParseConfirmTarget(const UniValue& value)
|
||||
unsigned int ParseConfirmTarget(const UniValue& value, unsigned int max_target)
|
||||
{
|
||||
int target = value.get_int();
|
||||
unsigned int max_target = ::feeEstimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
|
||||
if (target < 1 || (unsigned int)target > max_target) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid conf_target, must be between %u - %u", 1, max_target));
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ CScript CreateMultisigRedeemscript(const int required, const std::vector<CPubKey
|
|||
UniValue DescribeAddress(const CTxDestination& dest);
|
||||
|
||||
//! Parse a confirm target option and raise an RPC error if it is invalid.
|
||||
unsigned int ParseConfirmTarget(const UniValue& value);
|
||||
unsigned int ParseConfirmTarget(const UniValue& value, unsigned int max_target);
|
||||
|
||||
RPCErrorCode RPCErrorFromTransactionError(TransactionError terr);
|
||||
UniValue JSONRPCTransactionError(TransactionError terr, const std::string& err_string = "");
|
||||
|
|
|
@ -144,7 +144,7 @@ Result CreateTransaction(const CWallet* wallet, const uint256& txid, const CCoin
|
|||
new_fee = total_fee;
|
||||
nNewFeeRate = CFeeRate(total_fee, maxNewTxSize);
|
||||
} else {
|
||||
new_fee = GetMinimumFee(*wallet, maxNewTxSize, coin_control, mempool, ::feeEstimator, nullptr /* FeeCalculation */);
|
||||
new_fee = GetMinimumFee(*wallet, maxNewTxSize, coin_control, nullptr /* FeeCalculation */);
|
||||
nNewFeeRate = CFeeRate(new_fee, maxNewTxSize);
|
||||
|
||||
// New fee rate must be at least old rate + minimum incremental relay rate
|
||||
|
@ -195,7 +195,7 @@ 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(*wallet, ::feeEstimator))) {
|
||||
if (poutput->nValue <= GetDustThreshold(*poutput, GetDiscardRate(*wallet))) {
|
||||
wallet->WalletLogPrintf("Bumping fee and discarding dust output\n");
|
||||
new_fee += poutput->nValue;
|
||||
mtx.vout.erase(mtx.vout.begin() + nOutput);
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include <wallet/fees.h>
|
||||
|
||||
#include <policy/policy.h>
|
||||
#include <txmempool.h>
|
||||
#include <util/system.h>
|
||||
#include <validation.h>
|
||||
#include <wallet/coincontrol.h>
|
||||
|
@ -19,9 +18,9 @@ CAmount GetRequiredFee(const CWallet& wallet, unsigned int nTxBytes)
|
|||
}
|
||||
|
||||
|
||||
CAmount GetMinimumFee(const CWallet& wallet, 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, FeeCalculation* feeCalc)
|
||||
{
|
||||
CAmount fee_needed = GetMinimumFeeRate(wallet, coin_control, pool, estimator, feeCalc).GetFee(nTxBytes);
|
||||
CAmount fee_needed = GetMinimumFeeRate(wallet, coin_control, feeCalc).GetFee(nTxBytes);
|
||||
// Always obey the maximum
|
||||
if (fee_needed > maxTxFee) {
|
||||
fee_needed = maxTxFee;
|
||||
|
@ -35,7 +34,7 @@ CFeeRate GetRequiredFeeRate(const CWallet& wallet)
|
|||
return std::max(wallet.m_min_fee, ::minRelayTxFee);
|
||||
}
|
||||
|
||||
CFeeRate GetMinimumFeeRate(const CWallet& wallet, const CCoinControl& coin_control, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation* feeCalc)
|
||||
CFeeRate GetMinimumFeeRate(const CWallet& wallet, const CCoinControl& coin_control, FeeCalculation* feeCalc)
|
||||
{
|
||||
/* User control of how to calculate fee uses the following parameter precedence:
|
||||
1. coin_control.m_feerate
|
||||
|
@ -64,7 +63,7 @@ CFeeRate GetMinimumFeeRate(const CWallet& wallet, const CCoinControl& coin_contr
|
|||
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);
|
||||
feerate_needed = wallet.chain().estimateSmartFee(target, conservative_estimate, feeCalc);
|
||||
if (feerate_needed == CFeeRate(0)) {
|
||||
// if we don't have enough data for estimateSmartFee, then use fallback fee
|
||||
feerate_needed = wallet.m_fallback_fee;
|
||||
|
@ -74,7 +73,7 @@ CFeeRate GetMinimumFeeRate(const CWallet& wallet, const CCoinControl& coin_contr
|
|||
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);
|
||||
CFeeRate min_mempool_feerate = wallet.chain().mempoolMinFee();
|
||||
if (feerate_needed < min_mempool_feerate) {
|
||||
feerate_needed = min_mempool_feerate;
|
||||
if (feeCalc) feeCalc->reason = FeeReason::MEMPOOL_MIN;
|
||||
|
@ -90,10 +89,10 @@ CFeeRate GetMinimumFeeRate(const CWallet& wallet, const CCoinControl& coin_contr
|
|||
return feerate_needed;
|
||||
}
|
||||
|
||||
CFeeRate GetDiscardRate(const CWallet& wallet, const CBlockPolicyEstimator& estimator)
|
||||
CFeeRate GetDiscardRate(const CWallet& wallet)
|
||||
{
|
||||
unsigned int highest_target = estimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
|
||||
CFeeRate discard_rate = estimator.estimateSmartFee(highest_target, nullptr /* FeeCalculation */, false /* conservative */);
|
||||
unsigned int highest_target = wallet.chain().estimateMaxBlocks();
|
||||
CFeeRate discard_rate = wallet.chain().estimateSmartFee(highest_target, 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)) ? wallet.m_discard_rate : std::min(discard_rate, wallet.m_discard_rate);
|
||||
// Discard rate must be at least dustRelayFee
|
||||
|
|
|
@ -8,10 +8,8 @@
|
|||
|
||||
#include <amount.h>
|
||||
|
||||
class CBlockPolicyEstimator;
|
||||
class CCoinControl;
|
||||
class CFeeRate;
|
||||
class CTxMemPool;
|
||||
class CWallet;
|
||||
struct FeeCalculation;
|
||||
|
||||
|
@ -25,7 +23,7 @@ CAmount GetRequiredFee(const CWallet& wallet, unsigned int nTxBytes);
|
|||
* Estimate the minimum fee considering user set parameters
|
||||
* and the required fee
|
||||
*/
|
||||
CAmount GetMinimumFee(const CWallet& wallet, 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, FeeCalculation* feeCalc);
|
||||
|
||||
/**
|
||||
* Return the minimum required feerate taking into account the
|
||||
|
@ -37,11 +35,11 @@ CFeeRate GetRequiredFeeRate(const CWallet& wallet);
|
|||
* Estimate the minimum fee rate considering user set parameters
|
||||
* and the required fee
|
||||
*/
|
||||
CFeeRate GetMinimumFeeRate(const CWallet& wallet, const CCoinControl& coin_control, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation* feeCalc);
|
||||
CFeeRate GetMinimumFeeRate(const CWallet& wallet, const CCoinControl& coin_control, FeeCalculation* feeCalc);
|
||||
|
||||
/**
|
||||
* Return the maximum feerate for discarding change.
|
||||
*/
|
||||
CFeeRate GetDiscardRate(const CWallet& wallet, const CBlockPolicyEstimator& estimator);
|
||||
CFeeRate GetDiscardRate(const CWallet& wallet);
|
||||
|
||||
#endif // BITCOIN_WALLET_FEES_H
|
||||
|
|
|
@ -424,7 +424,7 @@ static UniValue sendtoaddress(const JSONRPCRequest& request)
|
|||
}
|
||||
|
||||
if (!request.params[6].isNull()) {
|
||||
coin_control.m_confirm_target = ParseConfirmTarget(request.params[6]);
|
||||
coin_control.m_confirm_target = ParseConfirmTarget(request.params[6], pwallet->chain().estimateMaxBlocks());
|
||||
}
|
||||
|
||||
if (!request.params[7].isNull()) {
|
||||
|
@ -884,7 +884,7 @@ static UniValue sendmany(const JSONRPCRequest& request)
|
|||
}
|
||||
|
||||
if (!request.params[6].isNull()) {
|
||||
coin_control.m_confirm_target = ParseConfirmTarget(request.params[6]);
|
||||
coin_control.m_confirm_target = ParseConfirmTarget(request.params[6], pwallet->chain().estimateMaxBlocks());
|
||||
}
|
||||
|
||||
if (!request.params[7].isNull()) {
|
||||
|
@ -2989,7 +2989,7 @@ void FundTransaction(CWallet* const pwallet, CMutableTransaction& tx, CAmount& f
|
|||
if (options.exists("feeRate")) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both conf_target and feeRate");
|
||||
}
|
||||
coinControl.m_confirm_target = ParseConfirmTarget(options["conf_target"]);
|
||||
coinControl.m_confirm_target = ParseConfirmTarget(options["conf_target"], pwallet->chain().estimateMaxBlocks());
|
||||
}
|
||||
if (options.exists("estimate_mode")) {
|
||||
if (options.exists("feeRate")) {
|
||||
|
@ -3279,7 +3279,7 @@ static UniValue bumpfee(const JSONRPCRequest& request)
|
|||
if (options.exists("confTarget") && options.exists("totalFee")) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "confTarget and totalFee options should not both be set. Please provide either a confirmation target for fee estimation or an explicit total fee for the transaction.");
|
||||
} else if (options.exists("confTarget")) { // TODO: alias this to conf_target
|
||||
coin_control.m_confirm_target = ParseConfirmTarget(options["confTarget"]);
|
||||
coin_control.m_confirm_target = ParseConfirmTarget(options["confTarget"], pwallet->chain().estimateMaxBlocks());
|
||||
} else if (options.exists("totalFee")) {
|
||||
totalFee = options["totalFee"].get_int64();
|
||||
if (totalFee <= 0) {
|
||||
|
|
|
@ -2485,10 +2485,10 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, const CoinEligibil
|
|||
FeeCalculation feeCalc;
|
||||
CCoinControl temp;
|
||||
temp.m_confirm_target = 1008;
|
||||
CFeeRate long_term_feerate = GetMinimumFeeRate(*this, temp, ::mempool, ::feeEstimator, &feeCalc);
|
||||
CFeeRate long_term_feerate = GetMinimumFeeRate(*this, temp, &feeCalc);
|
||||
|
||||
// Calculate cost of change
|
||||
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);
|
||||
CAmount cost_of_change = GetDiscardRate(*this).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 (OutputGroup& group : groups) {
|
||||
|
@ -2858,10 +2858,10 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
|
|||
CTxOut change_prototype_txout(0, scriptChange);
|
||||
coin_selection_params.change_output_size = GetSerializeSize(change_prototype_txout);
|
||||
|
||||
CFeeRate discard_rate = GetDiscardRate(*this, ::feeEstimator);
|
||||
CFeeRate discard_rate = GetDiscardRate(*this);
|
||||
|
||||
// Get the fee rate to use effective values in coin selection
|
||||
CFeeRate nFeeRateNeeded = GetMinimumFeeRate(*this, coin_control, ::mempool, ::feeEstimator, &feeCalc);
|
||||
CFeeRate nFeeRateNeeded = GetMinimumFeeRate(*this, coin_control, &feeCalc);
|
||||
|
||||
nFeeRet = 0;
|
||||
bool pick_new_inputs = true;
|
||||
|
@ -2994,7 +2994,7 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
|
|||
return false;
|
||||
}
|
||||
|
||||
nFeeNeeded = GetMinimumFee(*this, nBytes, coin_control, ::mempool, ::feeEstimator, &feeCalc);
|
||||
nFeeNeeded = GetMinimumFee(*this, nBytes, coin_control, &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.");
|
||||
|
@ -3022,7 +3022,7 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
|
|||
// 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(*this, tx_size_with_change, coin_control, ::mempool, ::feeEstimator, nullptr);
|
||||
CAmount fee_needed_with_change = GetMinimumFee(*this, tx_size_with_change, coin_control, 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;
|
||||
|
|
|
@ -100,8 +100,6 @@ class CCoinControl;
|
|||
class COutput;
|
||||
class CReserveKey;
|
||||
class CScript;
|
||||
class CTxMemPool;
|
||||
class CBlockPolicyEstimator;
|
||||
class CWalletTx;
|
||||
struct FeeCalculation;
|
||||
enum class FeeEstimateMode;
|
||||
|
|
Loading…
Reference in a new issue