Closes #1854. z_sendmany selects more utxos to avoid dust change output.
This commit is contained in:
@@ -215,6 +215,14 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
||||
CAmount selectedUTXOAmount = 0;
|
||||
bool selectedUTXOCoinbase = false;
|
||||
if (isfromtaddr_) {
|
||||
// Get dust threshold
|
||||
CKey secret;
|
||||
secret.MakeNewKey(true);
|
||||
CScript scriptPubKey = GetScriptForDestination(secret.GetPubKey().GetID());
|
||||
CTxOut out(CAmount(1), scriptPubKey);
|
||||
CAmount dustThreshold = out.GetDustThreshold(minRelayTxFee);
|
||||
CAmount dustChange = -1;
|
||||
|
||||
std::vector<SendManyInputUTXO> selectedTInputs;
|
||||
for (SendManyInputUTXO & t : t_inputs_) {
|
||||
bool b = std::get<3>(t);
|
||||
@@ -224,9 +232,21 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
||||
selectedUTXOAmount += std::get<2>(t);
|
||||
selectedTInputs.push_back(t);
|
||||
if (selectedUTXOAmount >= targetAmount) {
|
||||
break;
|
||||
// Select another utxo if there is change less than the dust threshold.
|
||||
dustChange = selectedUTXOAmount - targetAmount;
|
||||
if (dustChange == 0 || dustChange >= dustThreshold) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there is transparent change, is it valid or is it dust?
|
||||
if (dustChange < dustThreshold && dustChange != 0) {
|
||||
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS,
|
||||
strprintf("Insufficient transparent funds, have %s, need %s more to avoid creating invalid change output %s (dust threshold is %s)",
|
||||
FormatMoney(t_inputs_total), FormatMoney(dustThreshold - dustChange), FormatMoney(dustChange), FormatMoney(dustThreshold)));
|
||||
}
|
||||
|
||||
t_inputs_ = selectedTInputs;
|
||||
t_inputs_total = selectedUTXOAmount;
|
||||
|
||||
@@ -772,6 +792,11 @@ bool AsyncRPCOperation_sendmany::find_utxos(bool fAcceptCoinbase=false) {
|
||||
t_inputs_.push_back(utxo);
|
||||
}
|
||||
|
||||
// sort in ascending order, so smaller utxos appear first
|
||||
std::sort(t_inputs_.begin(), t_inputs_.end(), [](SendManyInputUTXO i, SendManyInputUTXO j) -> bool {
|
||||
return ( std::get<2>(i) < std::get<2>(j));
|
||||
});
|
||||
|
||||
return t_inputs_.size() > 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user