2
2
// Distributed under the MIT software license, see the accompanying
3
3
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
4
5
+ #include < algorithm>
5
6
#include < consensus/amount.h>
6
7
#include < consensus/validation.h>
7
8
#include < interfaces/chain.h>
9
+ #include < numeric>
8
10
#include < policy/policy.h>
9
11
#include < script/signingprovider.h>
10
12
#include < util/check.h>
@@ -555,14 +557,24 @@ std::optional<SelectionResult> ChooseSelectionResult(const CWallet& wallet, cons
555
557
results.push_back (*srd_result);
556
558
}
557
559
558
- if (results.size () == 0 ) {
560
+ if (results.empty () ) {
559
561
// No solution found
560
562
return std::nullopt;
561
563
}
562
564
565
+ std::vector<SelectionResult> eligible_results;
566
+ std::copy_if (results.begin (), results.end (), std::back_inserter (eligible_results), [coin_selection_params](const SelectionResult& result) {
567
+ const auto initWeight{coin_selection_params.tx_noinputs_size * WITNESS_SCALE_FACTOR};
568
+ return initWeight + result.GetWeight () <= static_cast <int >(MAX_STANDARD_TX_WEIGHT);
569
+ });
570
+
571
+ if (eligible_results.empty ()) {
572
+ return std::nullopt;
573
+ }
574
+
563
575
// Choose the result with the least waste
564
576
// If the waste is the same, choose the one which spends more inputs.
565
- auto & best_result = *std::min_element (results .begin (), results .end ());
577
+ auto & best_result = *std::min_element (eligible_results .begin (), eligible_results .end ());
566
578
return best_result;
567
579
}
568
580
@@ -867,19 +879,16 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
867
879
const auto change_spend_fee = coin_selection_params.m_discard_feerate .GetFee (coin_selection_params.change_spend_size );
868
880
coin_selection_params.min_viable_change = std::max (change_spend_fee + 1 , dust);
869
881
882
+ // Static vsize overhead + outputs vsize. 4 nVersion, 4 nLocktime, 1 input count, 1 witness overhead (dummy, flag, stack size)
883
+ coin_selection_params.tx_noinputs_size = 10 + GetSizeOfCompactSize (vecSend.size ()); // bytes for output count
884
+
870
885
// vouts to the payees
871
- if (!coin_selection_params.m_subtract_fee_outputs ) {
872
- coin_selection_params.tx_noinputs_size = 10 ; // Static vsize overhead + outputs vsize. 4 nVersion, 4 nLocktime, 1 input count, 1 witness overhead (dummy, flag, stack size)
873
- coin_selection_params.tx_noinputs_size += GetSizeOfCompactSize (vecSend.size ()); // bytes for output count
874
- }
875
886
for (const auto & recipient : vecSend)
876
887
{
877
888
CTxOut txout (recipient.nAmount , recipient.scriptPubKey );
878
889
879
890
// Include the fee cost for outputs.
880
- if (!coin_selection_params.m_subtract_fee_outputs ) {
881
- coin_selection_params.tx_noinputs_size += ::GetSerializeSize (txout, PROTOCOL_VERSION);
882
- }
891
+ coin_selection_params.tx_noinputs_size += ::GetSerializeSize (txout, PROTOCOL_VERSION);
883
892
884
893
if (IsDust (txout, wallet.chain ().relayDustFee ())) {
885
894
return util::Error{_ (" Transaction amount too small" )};
@@ -888,7 +897,7 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
888
897
}
889
898
890
899
// Include the fees for things that aren't inputs, excluding the change output
891
- const CAmount not_input_fees = coin_selection_params.m_effective_feerate .GetFee (coin_selection_params.tx_noinputs_size );
900
+ 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 );
892
901
CAmount selection_target = recipients_sum + not_input_fees;
893
902
894
903
// Fetch manually selected coins
0 commit comments