@@ -961,69 +961,48 @@ static std::optional<CreatedTransactionResult> CreateTransactionInternal(
961961 return CreatedTransactionResult (tx, nFeeRet, nChangePosInOut);
962962}
963963
964- // TODO: also return std::optional<CreatedTransactionResult> here in order
965- // to eliminate the out parameters and to simplify the function
966- bool CreateTransaction (
964+ std::optional<CreatedTransactionResult> CreateTransaction (
967965 CWallet& wallet,
968966 const std::vector<CRecipient>& vecSend,
969- CTransactionRef& tx,
970- CAmount& nFeeRet,
971- int & nChangePosInOut,
967+ int change_pos,
972968 bilingual_str& error,
973969 const CCoinControl& coin_control,
974970 FeeCalculation& fee_calc_out,
975971 bool sign)
976972{
977973 if (vecSend.empty ()) {
978974 error = _ (" Transaction must have at least one recipient" );
979- return false ;
975+ return std:: nullopt ;
980976 }
981977
982978 if (std::any_of (vecSend.cbegin (), vecSend.cend (), [](const auto & recipient){ return recipient.nAmount < 0 ; })) {
983979 error = _ (" Transaction amounts must not be negative" );
984- return false ;
980+ return std:: nullopt ;
985981 }
986982
987983 LOCK (wallet.cs_wallet );
988984
989- int nChangePosIn = nChangePosInOut;
990- Assert (!tx); // tx is an out-param. TODO change the return type from bool to tx (or nullptr)
991- std::optional<CreatedTransactionResult> txr_ungrouped = CreateTransactionInternal (wallet, vecSend, nChangePosInOut, error, coin_control, fee_calc_out, sign);
992- bool res = false ;
993- if (txr_ungrouped) {
994- tx = txr_ungrouped->tx ;
995- nFeeRet = txr_ungrouped->fee ;
996- nChangePosInOut = txr_ungrouped->change_pos ;
997- res = true ;
998- }
999- TRACE4 (coin_selection, normal_create_tx_internal, wallet.GetName ().c_str (), res, nFeeRet, nChangePosInOut);
985+ std::optional<CreatedTransactionResult> txr_ungrouped = CreateTransactionInternal (wallet, vecSend, change_pos, error, coin_control, fee_calc_out, sign);
986+ TRACE4 (coin_selection, normal_create_tx_internal, wallet.GetName ().c_str (), txr_ungrouped.has_value (),
987+ txr_ungrouped.has_value () ? txr_ungrouped->fee : 0 , txr_ungrouped.has_value () ? txr_ungrouped->change_pos : 0 );
988+ if (!txr_ungrouped) return std::nullopt ;
1000989 // try with avoidpartialspends unless it's enabled already
1001- if (res && nFeeRet > 0 /* 0 means non-functional fee rate estimation */ && wallet.m_max_aps_fee > -1 && !coin_control.m_avoid_partial_spends ) {
990+ if (txr_ungrouped-> fee > 0 /* 0 means non-functional fee rate estimation */ && wallet.m_max_aps_fee > -1 && !coin_control.m_avoid_partial_spends ) {
1002991 TRACE1 (coin_selection, attempting_aps_create_tx, wallet.GetName ().c_str ());
1003992 CCoinControl tmp_cc = coin_control;
1004993 tmp_cc.m_avoid_partial_spends = true ;
1005- CAmount nFeeRet2;
1006- CTransactionRef tx2;
1007- int nChangePosInOut2 = nChangePosIn;
1008994 bilingual_str error2; // fired and forgotten; if an error occurs, we discard the results
1009- std::optional<CreatedTransactionResult> txr_grouped = CreateTransactionInternal (wallet, vecSend, nChangePosInOut2 , error2, tmp_cc, fee_calc_out, sign);
995+ std::optional<CreatedTransactionResult> txr_grouped = CreateTransactionInternal (wallet, vecSend, change_pos , error2, tmp_cc, fee_calc_out, sign);
1010996 if (txr_grouped) {
1011- tx2 = txr_grouped->tx ;
1012- nFeeRet2 = txr_grouped->fee ;
1013- nChangePosInOut2 = txr_grouped->change_pos ;
1014-
1015997 // if fee of this alternative one is within the range of the max fee, we use this one
1016- const bool use_aps = nFeeRet2 <= nFeeRet + wallet.m_max_aps_fee ;
1017- wallet.WalletLogPrintf (" Fee non-grouped = %lld, grouped = %lld, using %s\n " , nFeeRet, nFeeRet2, use_aps ? " grouped" : " non-grouped" );
1018- TRACE5 (coin_selection, aps_create_tx_internal, wallet.GetName ().c_str (), use_aps, res, nFeeRet2, nChangePosInOut2);
1019- if (use_aps) {
1020- tx = tx2;
1021- nFeeRet = nFeeRet2;
1022- nChangePosInOut = nChangePosInOut2;
1023- }
998+ const bool use_aps = txr_grouped->fee <= txr_ungrouped->fee + wallet.m_max_aps_fee ;
999+ wallet.WalletLogPrintf (" Fee non-grouped = %lld, grouped = %lld, using %s\n " ,
1000+ txr_ungrouped->fee , txr_grouped->fee , use_aps ? " grouped" : " non-grouped" );
1001+ TRACE5 (coin_selection, aps_create_tx_internal, wallet.GetName ().c_str (), use_aps, true , txr_grouped->fee , txr_grouped->change_pos );
1002+ if (use_aps) return txr_grouped;
10241003 }
10251004 }
1026- return res ;
1005+ return txr_ungrouped ;
10271006}
10281007
10291008bool FundTransaction (CWallet& wallet, CMutableTransaction& tx, CAmount& nFeeRet, int & nChangePosInOut, bilingual_str& error, bool lockUnspents, const std::set<int >& setSubtractFeeFromOutputs, CCoinControl coinControl)
@@ -1047,11 +1026,12 @@ bool FundTransaction(CWallet& wallet, CMutableTransaction& tx, CAmount& nFeeRet,
10471026 // CreateTransaction call and LockCoin calls (when lockUnspents is true).
10481027 LOCK (wallet.cs_wallet );
10491028
1050- CTransactionRef tx_new;
10511029 FeeCalculation fee_calc_out;
1052- if (!CreateTransaction (wallet, vecSend, tx_new, nFeeRet, nChangePosInOut, error, coinControl, fee_calc_out, false )) {
1053- return false ;
1054- }
1030+ std::optional<CreatedTransactionResult> txr = CreateTransaction (wallet, vecSend, nChangePosInOut, error, coinControl, fee_calc_out, false );
1031+ if (!txr) return false ;
1032+ CTransactionRef tx_new = txr->tx ;
1033+ nFeeRet = txr->fee ;
1034+ nChangePosInOut = txr->change_pos ;
10551035
10561036 if (nChangePosInOut != -1 ) {
10571037 tx.vout .insert (tx.vout .begin () + nChangePosInOut, tx_new->vout [nChangePosInOut]);
0 commit comments