@@ -1008,12 +1008,20 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
10081008
10091009 // Set the long term feerate estimate to the wallet's consolidate feerate
10101010 coin_selection_params.m_long_term_feerate = wallet.m_consolidate_feerate ;
1011+ // Static vsize overhead + outputs vsize. 4 nVersion, 4 nLocktime, 1 input count, 1 witness overhead (dummy, flag, stack size)
1012+ coin_selection_params.tx_noinputs_size = 10 + GetSizeOfCompactSize (vecSend.size ()); // bytes for output count
10111013
10121014 CAmount recipients_sum = 0 ;
10131015 const OutputType change_type = wallet.TransactionChangeType (coin_control.m_change_type ? *coin_control.m_change_type : wallet.m_default_change_type , vecSend);
10141016 ReserveDestination reservedest (&wallet, change_type);
10151017 unsigned int outputs_to_subtract_fee_from = 0 ; // The number of outputs which we are subtracting the fee from
10161018 for (const auto & recipient : vecSend) {
1019+ if (IsDust (recipient, wallet.chain ().relayDustFee ())) {
1020+ return util::Error{_ (" Transaction amount too small" )};
1021+ }
1022+
1023+ // Include the fee cost for outputs.
1024+ coin_selection_params.tx_noinputs_size += GetSerializeSizeForRecipient (recipient);
10171025 recipients_sum += recipient.nAmount ;
10181026
10191027 if (recipient.fSubtractFeeFromAmount ) {
@@ -1098,23 +1106,6 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
10981106 const auto change_spend_fee = coin_selection_params.m_discard_feerate .GetFee (coin_selection_params.change_spend_size );
10991107 coin_selection_params.min_viable_change = std::max (change_spend_fee + 1 , dust);
11001108
1101- // Static vsize overhead + outputs vsize. 4 version, 4 nLocktime, 1 input count, 1 witness overhead (dummy, flag, stack size)
1102- coin_selection_params.tx_noinputs_size = 10 + GetSizeOfCompactSize (vecSend.size ()); // bytes for output count
1103-
1104- // vouts to the payees
1105- for (const auto & recipient : vecSend)
1106- {
1107- CTxOut txout (recipient.nAmount , GetScriptForDestination (recipient.dest ));
1108-
1109- // Include the fee cost for outputs.
1110- coin_selection_params.tx_noinputs_size += GetSerializeSizeForRecipient (recipient);
1111-
1112- if (IsDust (recipient, wallet.chain ().relayDustFee ())) {
1113- return util::Error{_ (" Transaction amount too small" )};
1114- }
1115- txNew.vout .push_back (txout);
1116- }
1117-
11181109 // Include the fees for things that aren't inputs, excluding the change output
11191110 const CAmount not_input_fees = coin_selection_params.m_effective_feerate .GetFee (coin_selection_params.m_subtract_fee_outputs ? 0 : coin_selection_params.tx_noinputs_size );
11201111 CAmount selection_target = recipients_sum + not_input_fees;
@@ -1155,6 +1146,11 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
11551146 result.GetWaste (),
11561147 result.GetSelectedValue ());
11571148
1149+ // vouts to the payees
1150+ for (const auto & recipient : vecSend)
1151+ {
1152+ txNew.vout .emplace_back (recipient.nAmount , GetScriptForDestination (recipient.dest ));
1153+ }
11581154 const CAmount change_amount = result.GetChange (coin_selection_params.min_viable_change , coin_selection_params.m_change_fee );
11591155 if (change_amount > 0 ) {
11601156 CTxOut newTxOut (change_amount, scriptChange);
0 commit comments