Skip to content

Commit c2ab38b

Browse files
committed
Merge #10284: Always log debug information for fee calculation in CreateTransaction
1bebfc8 Output Fee Estimation Calculations in CreateTransaction (Alex Morcos) Tree-SHA512: e25a27f7acbbc3a666d5d85da2554c5aaec4c923ee2fdbcfc532c29c6fbdec3c9e0d6ae6044543ecc339e7bd81df09c8d228e0b53a2c5c2dae0f1098c9453272
2 parents 7c72fb9 + 1bebfc8 commit c2ab38b

File tree

7 files changed

+134
-44
lines changed

7 files changed

+134
-44
lines changed

src/policy/fees.cpp

Lines changed: 68 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,26 @@
1616

1717
static constexpr double INF_FEERATE = 1e99;
1818

19+
std::string StringForFeeReason(FeeReason reason) {
20+
static const std::map<FeeReason, std::string> fee_reason_strings = {
21+
{FeeReason::NONE, "None"},
22+
{FeeReason::HALF_ESTIMATE, "Half Target 60% Threshold"},
23+
{FeeReason::FULL_ESTIMATE, "Target 85% Threshold"},
24+
{FeeReason::DOUBLE_ESTIMATE, "Double Target 95% Threshold"},
25+
{FeeReason::CONSERVATIVE, "Conservative Double Target longer horizon"},
26+
{FeeReason::MEMPOOL_MIN, "Mempool Min Fee"},
27+
{FeeReason::PAYTXFEE, "PayTxFee set"},
28+
{FeeReason::FALLBACK, "Fallback fee"},
29+
{FeeReason::REQUIRED, "Minimum Required Fee"},
30+
{FeeReason::MAXTXFEE, "MaxTxFee limit"}
31+
};
32+
auto reason_string = fee_reason_strings.find(reason);
33+
34+
if (reason_string == fee_reason_strings.end()) return "Unknown";
35+
36+
return reason_string->second;
37+
}
38+
1939
/**
2040
* We will instantiate an instance of this class to track transactions that were
2141
* included in a block. We will lump transactions into a bucket according to their
@@ -698,31 +718,36 @@ unsigned int CBlockPolicyEstimator::MaxUsableEstimate() const
698718
* time horizon which tracks confirmations up to the desired target. If
699719
* checkShorterHorizon is requested, also allow short time horizon estimates
700720
* for a lower target to reduce the given answer */
701-
double CBlockPolicyEstimator::estimateCombinedFee(unsigned int confTarget, double successThreshold, bool checkShorterHorizon) const
721+
double CBlockPolicyEstimator::estimateCombinedFee(unsigned int confTarget, double successThreshold, bool checkShorterHorizon, EstimationResult *result) const
702722
{
703723
double estimate = -1;
704724
if (confTarget >= 1 && confTarget <= longStats->GetMaxConfirms()) {
705725
// Find estimate from shortest time horizon possible
706726
if (confTarget <= shortStats->GetMaxConfirms()) { // short horizon
707-
estimate = shortStats->EstimateMedianVal(confTarget, SUFFICIENT_TXS_SHORT, successThreshold, true, nBestSeenHeight);
727+
estimate = shortStats->EstimateMedianVal(confTarget, SUFFICIENT_TXS_SHORT, successThreshold, true, nBestSeenHeight, result);
708728
}
709729
else if (confTarget <= feeStats->GetMaxConfirms()) { // medium horizon
710-
estimate = feeStats->EstimateMedianVal(confTarget, SUFFICIENT_FEETXS, successThreshold, true, nBestSeenHeight);
730+
estimate = feeStats->EstimateMedianVal(confTarget, SUFFICIENT_FEETXS, successThreshold, true, nBestSeenHeight, result);
711731
}
712732
else { // long horizon
713-
estimate = longStats->EstimateMedianVal(confTarget, SUFFICIENT_FEETXS, successThreshold, true, nBestSeenHeight);
733+
estimate = longStats->EstimateMedianVal(confTarget, SUFFICIENT_FEETXS, successThreshold, true, nBestSeenHeight, result);
714734
}
715735
if (checkShorterHorizon) {
736+
EstimationResult tempResult;
716737
// If a lower confTarget from a more recent horizon returns a lower answer use it.
717738
if (confTarget > feeStats->GetMaxConfirms()) {
718-
double medMax = feeStats->EstimateMedianVal(feeStats->GetMaxConfirms(), SUFFICIENT_FEETXS, successThreshold, true, nBestSeenHeight);
719-
if (medMax > 0 && (estimate == -1 || medMax < estimate))
739+
double medMax = feeStats->EstimateMedianVal(feeStats->GetMaxConfirms(), SUFFICIENT_FEETXS, successThreshold, true, nBestSeenHeight, &tempResult);
740+
if (medMax > 0 && (estimate == -1 || medMax < estimate)) {
720741
estimate = medMax;
742+
if (result) *result = tempResult;
743+
}
721744
}
722745
if (confTarget > shortStats->GetMaxConfirms()) {
723-
double shortMax = shortStats->EstimateMedianVal(shortStats->GetMaxConfirms(), SUFFICIENT_TXS_SHORT, successThreshold, true, nBestSeenHeight);
724-
if (shortMax > 0 && (estimate == -1 || shortMax < estimate))
746+
double shortMax = shortStats->EstimateMedianVal(shortStats->GetMaxConfirms(), SUFFICIENT_TXS_SHORT, successThreshold, true, nBestSeenHeight, &tempResult);
747+
if (shortMax > 0 && (estimate == -1 || shortMax < estimate)) {
725748
estimate = shortMax;
749+
if (result) *result = tempResult;
750+
}
726751
}
727752
}
728753
}
@@ -732,16 +757,18 @@ double CBlockPolicyEstimator::estimateCombinedFee(unsigned int confTarget, doubl
732757
/** Ensure that for a conservative estimate, the DOUBLE_SUCCESS_PCT is also met
733758
* at 2 * target for any longer time horizons.
734759
*/
735-
double CBlockPolicyEstimator::estimateConservativeFee(unsigned int doubleTarget) const
760+
double CBlockPolicyEstimator::estimateConservativeFee(unsigned int doubleTarget, EstimationResult *result) const
736761
{
737762
double estimate = -1;
763+
EstimationResult tempResult;
738764
if (doubleTarget <= shortStats->GetMaxConfirms()) {
739-
estimate = feeStats->EstimateMedianVal(doubleTarget, SUFFICIENT_FEETXS, DOUBLE_SUCCESS_PCT, true, nBestSeenHeight);
765+
estimate = feeStats->EstimateMedianVal(doubleTarget, SUFFICIENT_FEETXS, DOUBLE_SUCCESS_PCT, true, nBestSeenHeight, result);
740766
}
741767
if (doubleTarget <= feeStats->GetMaxConfirms()) {
742-
double longEstimate = longStats->EstimateMedianVal(doubleTarget, SUFFICIENT_FEETXS, DOUBLE_SUCCESS_PCT, true, nBestSeenHeight);
768+
double longEstimate = longStats->EstimateMedianVal(doubleTarget, SUFFICIENT_FEETXS, DOUBLE_SUCCESS_PCT, true, nBestSeenHeight, &tempResult);
743769
if (longEstimate > estimate) {
744770
estimate = longEstimate;
771+
if (result) *result = tempResult;
745772
}
746773
}
747774
return estimate;
@@ -754,12 +781,15 @@ double CBlockPolicyEstimator::estimateConservativeFee(unsigned int doubleTarget)
754781
* estimates, however, required the 95% threshold at 2 * target be met for any
755782
* longer time horizons also.
756783
*/
757-
CFeeRate CBlockPolicyEstimator::estimateSmartFee(int confTarget, int *answerFoundAtTarget, const CTxMemPool& pool, bool conservative) const
784+
CFeeRate CBlockPolicyEstimator::estimateSmartFee(int confTarget, FeeCalculation *feeCalc, const CTxMemPool& pool, bool conservative) const
758785
{
759-
if (answerFoundAtTarget)
760-
*answerFoundAtTarget = confTarget;
786+
if (feeCalc) {
787+
feeCalc->desiredTarget = confTarget;
788+
feeCalc->returnedTarget = confTarget;
789+
}
761790

762791
double median = -1;
792+
EstimationResult tempResult;
763793
{
764794
LOCK(cs_feeEstimator);
765795

@@ -780,7 +810,6 @@ CFeeRate CBlockPolicyEstimator::estimateSmartFee(int confTarget, int *answerFoun
780810
}
781811

782812
assert(confTarget > 0); //estimateCombinedFee and estimateConservativeFee take unsigned ints
783-
784813
/** true is passed to estimateCombined fee for target/2 and target so
785814
* that we check the max confirms for shorter time horizons as well.
786815
* This is necessary to preserve monotonically increasing estimates.
@@ -791,32 +820,49 @@ CFeeRate CBlockPolicyEstimator::estimateSmartFee(int confTarget, int *answerFoun
791820
* the purpose of conservative estimates is not to let short term
792821
* fluctuations lower our estimates by too much.
793822
*/
794-
double halfEst = estimateCombinedFee(confTarget/2, HALF_SUCCESS_PCT, true);
795-
double actualEst = estimateCombinedFee(confTarget, SUCCESS_PCT, true);
796-
double doubleEst = estimateCombinedFee(2 * confTarget, DOUBLE_SUCCESS_PCT, !conservative);
823+
double halfEst = estimateCombinedFee(confTarget/2, HALF_SUCCESS_PCT, true, &tempResult);
824+
if (feeCalc) {
825+
feeCalc->est = tempResult;
826+
feeCalc->reason = FeeReason::HALF_ESTIMATE;
827+
}
797828
median = halfEst;
829+
double actualEst = estimateCombinedFee(confTarget, SUCCESS_PCT, true, &tempResult);
798830
if (actualEst > median) {
799831
median = actualEst;
832+
if (feeCalc) {
833+
feeCalc->est = tempResult;
834+
feeCalc->reason = FeeReason::FULL_ESTIMATE;
835+
}
800836
}
837+
double doubleEst = estimateCombinedFee(2 * confTarget, DOUBLE_SUCCESS_PCT, !conservative, &tempResult);
801838
if (doubleEst > median) {
802839
median = doubleEst;
840+
if (feeCalc) {
841+
feeCalc->est = tempResult;
842+
feeCalc->reason = FeeReason::DOUBLE_ESTIMATE;
843+
}
803844
}
804845

805846
if (conservative || median == -1) {
806-
double consEst = estimateConservativeFee(2 * confTarget);
847+
double consEst = estimateConservativeFee(2 * confTarget, &tempResult);
807848
if (consEst > median) {
808849
median = consEst;
850+
if (feeCalc) {
851+
feeCalc->est = tempResult;
852+
feeCalc->reason = FeeReason::CONSERVATIVE;
853+
}
809854
}
810855
}
811856
} // Must unlock cs_feeEstimator before taking mempool locks
812857

813-
if (answerFoundAtTarget)
814-
*answerFoundAtTarget = confTarget;
858+
if (feeCalc) feeCalc->returnedTarget = confTarget;
815859

816860
// If mempool is limiting txs , return at least the min feerate from the mempool
817861
CAmount minPoolFee = pool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFeePerK();
818-
if (minPoolFee > 0 && minPoolFee > median)
862+
if (minPoolFee > 0 && minPoolFee > median) {
863+
if (feeCalc) feeCalc->reason = FeeReason::MEMPOOL_MIN;
819864
return CFeeRate(minPoolFee);
865+
}
820866

821867
if (median < 0)
822868
return CFeeRate(0);

src/policy/fees.h

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,22 @@ enum FeeEstimateHorizon {
7474
LONG_HALFLIFE = 2
7575
};
7676

77+
/* Enumeration of reason for returned fee estimate */
78+
enum class FeeReason {
79+
NONE,
80+
HALF_ESTIMATE,
81+
FULL_ESTIMATE,
82+
DOUBLE_ESTIMATE,
83+
CONSERVATIVE,
84+
MEMPOOL_MIN,
85+
PAYTXFEE,
86+
FALLBACK,
87+
REQUIRED,
88+
MAXTXFEE,
89+
};
90+
91+
std::string StringForFeeReason(FeeReason reason);
92+
7793
/* Used to return detailed information about a feerate bucket */
7894
struct EstimatorBucket
7995
{
@@ -90,8 +106,16 @@ struct EstimationResult
90106
{
91107
EstimatorBucket pass;
92108
EstimatorBucket fail;
93-
double decay;
94-
unsigned int scale;
109+
double decay = 0;
110+
unsigned int scale = 0;
111+
};
112+
113+
struct FeeCalculation
114+
{
115+
EstimationResult est;
116+
FeeReason reason = FeeReason::NONE;
117+
int desiredTarget = 0;
118+
int returnedTarget = 0;
95119
};
96120

97121
/**
@@ -173,7 +197,7 @@ class CBlockPolicyEstimator
173197
* the closest target where one can be given. 'conservative' estimates are
174198
* valid over longer time horizons also.
175199
*/
176-
CFeeRate estimateSmartFee(int confTarget, int *answerFoundAtTarget, const CTxMemPool& pool, bool conservative = true) const;
200+
CFeeRate estimateSmartFee(int confTarget, FeeCalculation *feeCalc, const CTxMemPool& pool, bool conservative = true) const;
177201

178202
/** Return a specific fee estimate calculation with a given success
179203
* threshold and time horizon, and optionally return detailed data about
@@ -223,9 +247,9 @@ class CBlockPolicyEstimator
223247
bool processBlockTx(unsigned int nBlockHeight, const CTxMemPoolEntry* entry);
224248

225249
/** Helper for estimateSmartFee */
226-
double estimateCombinedFee(unsigned int confTarget, double successThreshold, bool checkShorterHorizon) const;
250+
double estimateCombinedFee(unsigned int confTarget, double successThreshold, bool checkShorterHorizon, EstimationResult *result) const;
227251
/** Helper for estimateSmartFee */
228-
double estimateConservativeFee(unsigned int doubleTarget) const;
252+
double estimateConservativeFee(unsigned int doubleTarget, EstimationResult *result) const;
229253
/** Number of blocks of data recorded while fee estimates have been running */
230254
unsigned int BlockSpan() const;
231255
/** Number of blocks of recorded fee estimate data represented in saved data file */

src/qt/sendcoinsdialog.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -651,8 +651,8 @@ void SendCoinsDialog::updateSmartFeeLabel()
651651
return;
652652

653653
int nBlocksToConfirm = ui->sliderSmartFee->maximum() - ui->sliderSmartFee->value() + 2;
654-
int estimateFoundAtBlocks = nBlocksToConfirm;
655-
CFeeRate feeRate = ::feeEstimator.estimateSmartFee(nBlocksToConfirm, &estimateFoundAtBlocks, ::mempool);
654+
FeeCalculation feeCalc;
655+
CFeeRate feeRate = ::feeEstimator.estimateSmartFee(nBlocksToConfirm, &feeCalc, ::mempool);
656656
if (feeRate <= CFeeRate(0)) // not enough data => minfee
657657
{
658658
ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(),
@@ -670,7 +670,7 @@ void SendCoinsDialog::updateSmartFeeLabel()
670670
ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(),
671671
std::max(feeRate.GetFeePerK(), CWallet::GetRequiredFee(1000))) + "/kB");
672672
ui->labelSmartFee2->hide();
673-
ui->labelFeeEstimation->setText(tr("Estimated to begin confirmation within %n block(s).", "", estimateFoundAtBlocks));
673+
ui->labelFeeEstimation->setText(tr("Estimated to begin confirmation within %n block(s).", "", feeCalc.returnedTarget));
674674
ui->fallbackFeeWarningLabel->setVisible(false);
675675
}
676676

src/rpc/mining.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -867,10 +867,10 @@ UniValue estimatesmartfee(const JSONRPCRequest& request)
867867
}
868868

869869
UniValue result(UniValue::VOBJ);
870-
int answerFound;
871-
CFeeRate feeRate = ::feeEstimator.estimateSmartFee(nBlocks, &answerFound, ::mempool, conservative);
870+
FeeCalculation feeCalc;
871+
CFeeRate feeRate = ::feeEstimator.estimateSmartFee(nBlocks, &feeCalc, ::mempool, conservative);
872872
result.push_back(Pair("feerate", feeRate == CFeeRate(0) ? -1.0 : ValueFromAmount(feeRate.GetFeePerK())));
873-
result.push_back(Pair("blocks", answerFound));
873+
result.push_back(Pair("blocks", feeCalc.returnedTarget));
874874
return result;
875875
}
876876

src/wallet/feebumper.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ 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, ignoreGlobalPayTxFee);
168+
nNewFee = CWallet::GetMinimumFee(maxNewTxSize, newConfirmTarget, mempool, ::feeEstimator, nullptr, ignoreGlobalPayTxFee);
169169
nNewFeeRate = CFeeRate(nNewFee, maxNewTxSize);
170170

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

src/wallet/wallet.cpp

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2534,7 +2534,8 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
25342534

25352535
assert(txNew.nLockTime <= (unsigned int)chainActive.Height());
25362536
assert(txNew.nLockTime < LOCKTIME_THRESHOLD);
2537-
2537+
FeeCalculation feeCalc;
2538+
unsigned int nBytes;
25382539
{
25392540
std::set<CInputCoin> setCoins;
25402541
LOCK2(cs_main, cs_wallet);
@@ -2706,7 +2707,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
27062707
return false;
27072708
}
27082709

2709-
unsigned int nBytes = GetVirtualTransactionSize(txNew);
2710+
nBytes = GetVirtualTransactionSize(txNew);
27102711

27112712
CTransaction txNewConst(txNew);
27122713

@@ -2721,7 +2722,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
27212722
if (coinControl && coinControl->nConfirmTarget > 0)
27222723
currentConfirmationTarget = coinControl->nConfirmTarget;
27232724

2724-
CAmount nFeeNeeded = GetMinimumFee(nBytes, currentConfirmationTarget, ::mempool, ::feeEstimator);
2725+
CAmount nFeeNeeded = GetMinimumFee(nBytes, currentConfirmationTarget, ::mempool, ::feeEstimator, &feeCalc);
27252726
if (coinControl && coinControl->fOverrideFeeRate)
27262727
nFeeNeeded = coinControl->nFeeRate.GetFee(nBytes);
27272728

@@ -2818,6 +2819,15 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT
28182819
return false;
28192820
}
28202821
}
2822+
2823+
LogPrintf("Fee Calculation: Fee:%d Bytes:%u Tgt:%d (requested %d) Reason:\"%s\" Decay %.5f: Estimation: (%g - %g) %.2f%% %.1f/(%.1f %d mem %.1f out) Fail: (%g - %g) %.2f%% %.1f/(%.1f %d mem %.1f out)\n",
2824+
nFeeRet, nBytes, feeCalc.returnedTarget, feeCalc.desiredTarget, StringForFeeReason(feeCalc.reason), feeCalc.est.decay,
2825+
feeCalc.est.pass.start, feeCalc.est.pass.end,
2826+
100 * feeCalc.est.pass.withinTarget / (feeCalc.est.pass.totalConfirmed + feeCalc.est.pass.inMempool + feeCalc.est.pass.leftMempool),
2827+
feeCalc.est.pass.withinTarget, feeCalc.est.pass.totalConfirmed, feeCalc.est.pass.inMempool, feeCalc.est.pass.leftMempool,
2828+
feeCalc.est.fail.start, feeCalc.est.fail.end,
2829+
100 * feeCalc.est.fail.withinTarget / (feeCalc.est.fail.totalConfirmed + feeCalc.est.fail.inMempool + feeCalc.est.fail.leftMempool),
2830+
feeCalc.est.fail.withinTarget, feeCalc.est.fail.totalConfirmed, feeCalc.est.fail.inMempool, feeCalc.est.fail.leftMempool);
28212831
return true;
28222832
}
28232833

@@ -2893,23 +2903,32 @@ CAmount CWallet::GetRequiredFee(unsigned int nTxBytes)
28932903
return std::max(minTxFee.GetFee(nTxBytes), ::minRelayTxFee.GetFee(nTxBytes));
28942904
}
28952905

2896-
CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, bool ignoreGlobalPayTxFee)
2906+
CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation *feeCalc, bool ignoreGlobalPayTxFee)
28972907
{
28982908
// payTxFee is the user-set global for desired feerate
28992909
CAmount nFeeNeeded = payTxFee.GetFee(nTxBytes);
29002910
// User didn't set: use -txconfirmtarget to estimate...
29012911
if (nFeeNeeded == 0 || ignoreGlobalPayTxFee) {
2902-
int estimateFoundTarget = nConfirmTarget;
2903-
nFeeNeeded = estimator.estimateSmartFee(nConfirmTarget, &estimateFoundTarget, pool).GetFee(nTxBytes);
2912+
nFeeNeeded = estimator.estimateSmartFee(nConfirmTarget, feeCalc, pool, true).GetFee(nTxBytes);
29042913
// ... unless we don't have enough mempool data for estimatefee, then use fallbackFee
2905-
if (nFeeNeeded == 0)
2914+
if (nFeeNeeded == 0) {
29062915
nFeeNeeded = fallbackFee.GetFee(nTxBytes);
2916+
if (feeCalc) feeCalc->reason = FeeReason::FALLBACK;
2917+
}
2918+
} else {
2919+
if (feeCalc) feeCalc->reason = FeeReason::PAYTXFEE;
29072920
}
29082921
// prevent user from paying a fee below minRelayTxFee or minTxFee
2909-
nFeeNeeded = std::max(nFeeNeeded, GetRequiredFee(nTxBytes));
2922+
CAmount requiredFee = GetRequiredFee(nTxBytes);
2923+
if (requiredFee > nFeeNeeded) {
2924+
nFeeNeeded = requiredFee;
2925+
if (feeCalc) feeCalc->reason = FeeReason::REQUIRED;
2926+
}
29102927
// But always obey the maximum
2911-
if (nFeeNeeded > maxTxFee)
2928+
if (nFeeNeeded > maxTxFee) {
29122929
nFeeNeeded = maxTxFee;
2930+
if (feeCalc) feeCalc->reason = FeeReason::MAXTXFEE;
2931+
}
29132932
return nFeeNeeded;
29142933
}
29152934

src/wallet/wallet.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ class CScheduler;
7777
class CTxMemPool;
7878
class CBlockPolicyEstimator;
7979
class CWalletTx;
80+
class FeeCalculation;
8081

8182
/** (client) version numbers for particular wallet features */
8283
enum WalletFeature
@@ -959,7 +960,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface
959960
* Estimate the minimum fee considering user set parameters
960961
* and the required fee
961962
*/
962-
static CAmount GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, bool ignoreGlobalPayTxFee = false);
963+
static CAmount GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation *feeCalc = nullptr, bool ignoreGlobalPayTxFee = false);
963964
/**
964965
* Return the minimum required fee taking into account the
965966
* floating relay fee and user set minimum transaction fee

0 commit comments

Comments
 (0)