From 0d5ecf4cb3e4c70f1821b5dbe59a59c97c83fa66 Mon Sep 17 00:00:00 2001 From: CaveSpectre11 <36988814+CaveSpectre11@users.noreply.github.com> Date: Tue, 26 Mar 2019 20:20:49 -0400 Subject: [PATCH 1/2] Correct issues with dust totaling near threshold A problem was introduced with #518 when a utxo smaller than 10% of the threshold takes the total combined coins above the threshold, or when the total amount of dust is less than 10% above the threshold. What occurs is two fold. First, the nTotalRewardsValue > nAutoCombineThreshold will break it out of the for loop; but the "safety margin" will split it up into two utxos, one within 10% of the threshold, and then the utxo for the change. When the wallet comes back through on it's dust collection, it can pick up those two utxos and repeat until the fees widdle the two combined transactions fall below the threshold. If there is another utxo to add in order to get us far enough above the threshold that the 10% reduction is still above the threshold; then we're now good when accounting for the 10% in our check in the for loop. However there is still one other case that slips through. If the total amount being collected falls into the "within 10% of the threshold" situation, and the for loop can't make another pass... we exit the for loop normally, and find our way into the zero fee check. However the zero fee check sees we are over the threshold, but not that the transaction amount will be over the threshold. So we need to account for the 10% there as well, by using the actual amount (vsecSend[0].second) rather than nTotalRewardsValue to determine if we should continue only if free. --- src/wallet.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/wallet.cpp b/src/wallet.cpp index 6593188b3afb..46f9cb083b14 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -4209,8 +4209,8 @@ void CWallet::AutoCombineDust() vRewardCoins.push_back(out); nTotalRewardsValue += out.Value(); - // Combine to the threshold and not way above - if (nTotalRewardsValue > nAutoCombineThreshold * COIN) + // Combine until our total is enough above the threshold to remain above after adjustments + if ((nTotalRewardsValue-nTotalRewardsValue/10) > nAutoCombineThreshold * COIN) break; // Around 180 bytes per input. We use 190 to be certain @@ -4256,7 +4256,7 @@ void CWallet::AutoCombineDust() } //we don't combine below the threshold unless the fees are 0 to avoid paying fees over fees over fees - if (!maxSize && nTotalRewardsValue < nAutoCombineThreshold * COIN && nFeeRet > 0) + if (!maxSize && vecSend[0].second < nAutoCombineThreshold * COIN && nFeeRet > 0) continue; if (!CommitTransaction(wtx, keyChange)) { @@ -4264,7 +4264,8 @@ void CWallet::AutoCombineDust() continue; } - LogPrintf("AutoCombineDust sent transaction\n"); + LogPrintf("AutoCombineDust sent transaction. Fee=%d, Total Value=%d Sending=%d\n", + nFeeRet, nTotalRewardsValue, vecSend[0].second); delete coinControl; } From b75c5ae3124d15d127c12c7fd9b26b09265f3df5 Mon Sep 17 00:00:00 2001 From: CaveSpectre11 <36988814+CaveSpectre11@users.noreply.github.com> Date: Wed, 27 Mar 2019 12:14:01 -0400 Subject: [PATCH 2/2] Update wallet.cpp --- src/wallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet.cpp b/src/wallet.cpp index 46f9cb083b14..a94016c7bc6a 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -4210,7 +4210,7 @@ void CWallet::AutoCombineDust() nTotalRewardsValue += out.Value(); // Combine until our total is enough above the threshold to remain above after adjustments - if ((nTotalRewardsValue-nTotalRewardsValue/10) > nAutoCombineThreshold * COIN) + if ((nTotalRewardsValue - nTotalRewardsValue / 10) > nAutoCombineThreshold * COIN) break; // Around 180 bytes per input. We use 190 to be certain