From ae2f68d655808d6070af015eb02f33d3de727314 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Thu, 31 Oct 2019 21:52:17 +0300 Subject: [PATCH 1/3] From 2 best sets with the same `nTotal` in ApproximateBestSubset prefer the one with less inputs --- src/wallet/wallet.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 38d827e0c348..e4708347e94c 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2863,6 +2863,7 @@ static void ApproximateBestSubset(const std::vector& vValue, const C vfBest.assign(vValue.size(), true); nBest = nTotalLower; + int nBestCount = 0; FastRandomContext insecure_rand; @@ -2870,6 +2871,7 @@ static void ApproximateBestSubset(const std::vector& vValue, const C { vfIncluded.assign(vValue.size(), false); CAmount nTotal = 0; + int nTotalCount = 0; bool fReachedTarget = false; for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++) { @@ -2884,16 +2886,19 @@ static void ApproximateBestSubset(const std::vector& vValue, const C if (nPass == 0 ? insecure_rand.randbool() : !vfIncluded[i]) { nTotal += vValue[i].txout.nValue; + ++nTotalCount; vfIncluded[i] = true; if (nTotal >= nTargetValue) { fReachedTarget = true; - if (nTotal < nBest) + if (nTotal < nBest || (nTotal == nBest && nTotalCount < nBestCount)) { nBest = nTotal; + nBestCount = nTotalCount; vfBest = vfIncluded; } nTotal -= vValue[i].txout.nValue; + --nTotalCount; vfIncluded[i] = false; } } From 5d89b84ee5a49d49a6374d17a4ae88430593f732 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Thu, 31 Oct 2019 21:54:47 +0300 Subject: [PATCH 2/3] There is no reason to run ApproximateBestSubset again if nMinChange is 0 --- src/wallet/wallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index e4708347e94c..5308162fcc39 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3052,7 +3052,7 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, const int nConfMin CAmount nBest; ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest); - if (nBest != nTargetValue && nTotalLower >= nTargetValue + nMinChange) + if (nBest != nTargetValue && nMinChange != 0 && nTotalLower >= nTargetValue + nMinChange) ApproximateBestSubset(vValue, nTotalLower, nTargetValue + nMinChange, vfBest, nBest); // If we have a bigger coin and (either the stochastic approximation didn't find a good solution, From e06f5a6c0d7aa21ae36a24e428be9daffc2c54fc Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Mon, 4 Nov 2019 14:01:32 +0300 Subject: [PATCH 3/3] Apply review suggestions --- src/wallet/wallet.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 5308162fcc39..95db20386183 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2863,7 +2863,7 @@ static void ApproximateBestSubset(const std::vector& vValue, const C vfBest.assign(vValue.size(), true); nBest = nTotalLower; - int nBestCount = 0; + int nBestInputCount = 0; FastRandomContext insecure_rand; @@ -2871,7 +2871,7 @@ static void ApproximateBestSubset(const std::vector& vValue, const C { vfIncluded.assign(vValue.size(), false); CAmount nTotal = 0; - int nTotalCount = 0; + int nTotalInputCount = 0; bool fReachedTarget = false; for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++) { @@ -2886,19 +2886,19 @@ static void ApproximateBestSubset(const std::vector& vValue, const C if (nPass == 0 ? insecure_rand.randbool() : !vfIncluded[i]) { nTotal += vValue[i].txout.nValue; - ++nTotalCount; + ++nTotalInputCount; vfIncluded[i] = true; if (nTotal >= nTargetValue) { fReachedTarget = true; - if (nTotal < nBest || (nTotal == nBest && nTotalCount < nBestCount)) + if (nTotal < nBest || (nTotal == nBest && nTotalInputCount < nBestInputCount)) { nBest = nTotal; - nBestCount = nTotalCount; + nBestInputCount = nTotalInputCount; vfBest = vfIncluded; } nTotal -= vValue[i].txout.nValue; - --nTotalCount; + --nTotalInputCount; vfIncluded[i] = false; } }