wallet: Fix bug in CreateTransaction causing insufficient fees #2029
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
CreateTransaction had a major bug where the provided set of coins was conflated with the output set of coins from SelectCoins(). This caused the second and succeeding iterations of the while loop to effectively be a no-op for improved coin selection to try and resolve any insufficient fee issues. (I.e. SelectCoins was never run again because on second and succeeding iterations of the while loop, the output set from the first SelectCoins invocation was then treated as if it was the inputs to the function as a whole and therefore nothing was done and you would end up in a negative change situation.)
Also there was a missing check for negative change, which was a double bug in the sense that if it had been there, it would have at least caught the former error. The check for negative change, in the case where there is a provided coin set, must be done to avoid going through the while loop more than twice. In the case where there is a provided set of coins, AND the change is greater than zero, but it gets to the calculation of the actual fees, and they are higher than the entering value of nTransactionFee, then the second iteration through, the nFeeRet could be higher than the available value from the inputs and therefore there would be negative change at this point. The function must return an error then, since the provided set of coins must be viewed as immutable, so there is no way to cover the fees.