diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2535,12 +2535,12 @@ std::vector vCoins(vAvailableCoins); Amount value_to_select = nTargetValue; + // Default to bnb was not used. If we use it, we set it later + bnb_used = false; + // coin control -> return all selected outputs (we want all selected to go // into the transaction for sure) if (coin_control.HasSelected() && !coin_control.fAllowOtherInputs) { - // We didn't use BnB here, so set it to false. - bnb_used = false; - for (const COutput &out : vCoins) { if (!out.fSpendable) { continue; @@ -2567,7 +2567,6 @@ const CWalletTx &wtx = it->second; // Clearly invalid input, fail if (wtx.tx->vout.size() <= outpoint.GetN()) { - bnb_used = false; return false; } // Just to calculate the marginal byte size @@ -2575,7 +2574,6 @@ wtx.GetSpendSize(outpoint.GetN(), false)); nValueFromPresetInputs += coin.txout.nValue; if (coin.m_input_bytes <= 0) { - bnb_used = false; // Not solvable, can't estimate size for fee return false; } @@ -2589,7 +2587,6 @@ } setPresetCoins.insert(coin); } else { - bnb_used = false; return false; // TODO: Allow non-wallet inputs } } @@ -3018,7 +3015,7 @@ } // Choose coins to use - bool bnb_used; + bool bnb_used = false; if (pick_new_inputs) { nValueIn = Amount::zero(); setCoins.clear(); diff --git a/test/functional/rpc_fundrawtransaction.py b/test/functional/rpc_fundrawtransaction.py --- a/test/functional/rpc_fundrawtransaction.py +++ b/test/functional/rpc_fundrawtransaction.py @@ -90,6 +90,7 @@ self.test_option_feerate() self.test_address_reuse() self.test_option_subtract_fee_from_outputs() + self.test_subtract_fee_with_presets() def test_change_position(self): # ensure that setting changePosition in fundraw with an exact match is @@ -848,6 +849,21 @@ # the total subtracted from the outputs is equal to the fee assert_equal(share[0] + share[2] + share[3], result[0]['fee']) + def test_subtract_fee_with_presets(self): + self.log.info( + "Test fundrawtxn subtract fee from outputs with preset inputs that are sufficient") + + addr = self.nodes[0].getnewaddress() + txid = self.nodes[0].sendtoaddress(addr, 10) + vout = find_vout_for_address(self.nodes[0], txid, addr) + + rawtx = self.nodes[0].createrawtransaction([{'txid': txid, 'vout': vout}], [ + {self.nodes[0].getnewaddress(): 5}]) + fundedtx = self.nodes[0].fundrawtransaction( + rawtx, {'subtractFeeFromOutputs': [0]}) + signedtx = self.nodes[0].signrawtransactionwithwallet(fundedtx['hex']) + self.nodes[0].sendrawtransaction(signedtx['hex']) + if __name__ == '__main__': RawTransactionsTest().main()