From 1a6a0b0dfb90f9ebd4b86d7934c6aa5594974f5f Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Thu, 4 Feb 2021 18:21:26 -0500 Subject: wallet: Use existing feerate instead of getting a new one During each loop of CreateTransaction, instead of constantly getting a new feerate, use the feerate that we have already fetched for all fee calculations. Thix fixes a race condition where the feerate required changes during each iteration of the loop. This commit changes behavior as the "Fee estimation failed" error will now take priority over "Signing transaction failed". --- src/wallet/wallet.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index db80745db0..31982a0901 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2814,6 +2814,11 @@ bool CWallet::CreateTransactionInternal( error = strprintf(_("Fee rate (%s) is lower than the minimum fee rate setting (%s)"), coin_control.m_feerate->ToString(FeeEstimateMode::SAT_VB), nFeeRateNeeded.ToString(FeeEstimateMode::SAT_VB)); return false; } + if (feeCalc.reason == FeeReason::FALLBACK && !m_allow_fallback_fee) { + // eventually allow a fallback fee + error = _("Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable -fallbackfee."); + return false; + } nFeeRet = 0; bool pick_new_inputs = true; @@ -2951,13 +2956,7 @@ bool CWallet::CreateTransactionInternal( return false; } - nFeeNeeded = GetMinimumFee(*this, nBytes, coin_control, &feeCalc); - if (feeCalc.reason == FeeReason::FALLBACK && !m_allow_fallback_fee) { - // eventually allow a fallback fee - error = _("Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable -fallbackfee."); - return false; - } - + nFeeNeeded = coin_selection_params.effective_fee.GetFee(nBytes); if (nFeeRet >= nFeeNeeded) { // Reduce fee to only the needed amount if possible. This // prevents potential overpayment in fees if the coins @@ -2971,7 +2970,7 @@ bool CWallet::CreateTransactionInternal( // 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, nullptr); + CAmount fee_needed_with_change = coin_selection_params.effective_fee.GetFee(tx_size_with_change); 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; -- cgit v1.2.3