diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index e6f202713..12f9aca5b 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5298,6 +5298,12 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk) CAmount total_value = 0; + // correctness: reserve the miner fee during note selection so we don't stop at exactly nTotalOut + // and then fail later with a spurious "insufficient funds". Mirrors the nFee computed below. + CAmount nFeeReserve = ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE; + if (params.size() > 3) + nFeeReserve = (params[3].get_real() == 0.0) ? 0 : AmountFromValue(params[3]); + std::vector saplingNoteInputs; // Decide which sapling notes will be spent for (const SaplingNoteEntry& entry : saplingEntries) { @@ -5309,8 +5315,8 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk) saplingNoteInputs.emplace_back(entry.op, entry.note, nValue, extsk.expsk); total_value += nValue; LogPrintf("%s: adding note to spend with value=%s, total_value=%s\n", __func__, FormatMoney(nValue), FormatMoney(total_value) ); - if (total_value >= nTotalOut) { - // we have enough note value to make the tx + if (total_value >= nTotalOut + nFeeReserve) { + // we have enough note value (incl. miner fee) to make the tx LogPrintf("%s: found enough notes, nTotalOut=%s total_value=%s\n", __func__, FormatMoney(nTotalOut), FormatMoney(total_value) ); break; }