@@ -686,6 +686,18 @@ bool CWallet::CreateTransactionInternal(
686686 // change keypool ran out, but change is required.
687687 CHECK_NONFATAL (IsValidDestination (dest) != scriptChange.empty ());
688688 }
689+ CTxOut change_prototype_txout (0 , scriptChange);
690+ coin_selection_params.change_output_size = GetSerializeSize (change_prototype_txout);
691+
692+ // Get size of spending the change output
693+ int change_spend_size = CalculateMaximumSignedInputSize (change_prototype_txout, this );
694+ // If the wallet doesn't know how to sign change output, assume p2sh-p2pkh
695+ // as lower-bound to allow BnB to do it's thing
696+ if (change_spend_size == -1 ) {
697+ coin_selection_params.change_spend_size = DUMMY_NESTED_P2PKH_INPUT_SIZE;
698+ } else {
699+ coin_selection_params.change_spend_size = (size_t )change_spend_size;
700+ }
689701
690702 // Set discard feerate
691703 coin_selection_params.m_discard_feerate = coin_control.m_discard_feerate ? *coin_control.m_discard_feerate : GetDiscardRate (*this );
@@ -704,12 +716,18 @@ bool CWallet::CreateTransactionInternal(
704716 return false ;
705717 }
706718
719+ // Get long term estimate
720+ CCoinControl cc_temp;
721+ cc_temp.m_confirm_target = chain ().estimateMaxBlocks ();
722+ coin_selection_params.m_long_term_feerate = GetMinimumFeeRate (*this , cc_temp, nullptr );
723+
707724 nFeeRet = 0 ;
708725 bool pick_new_inputs = true ;
709726 CAmount nValueIn = 0 ;
710727
711728 // BnB selector is the only selector used when this is true.
712729 coin_selection_params.use_bnb = false ; // Dash: never use BnB
730+ coin_selection_params.m_subtract_fee_outputs = nSubtractFeeFromAmount != 0 ; // If we are doing subtract fee from recipient, don't use effective values
713731
714732 CAmount nAmountToSelectAdditional{0 };
715733 // Start with nAmountToSelectAdditional=0 and loop until there is enough to cover the request + fees, try it 500 times.
@@ -726,7 +744,11 @@ bool CWallet::CreateTransactionInternal(
726744 assert (nAmountToSelectAdditional >= 0 );
727745 nValueToSelect += nAmountToSelectAdditional;
728746 }
747+
729748 // vouts to the payees
749+ if (!coin_selection_params.m_subtract_fee_outputs ) {
750+ coin_selection_params.tx_noinputs_size = 10 ; // Static vsize overhead + outputs vsize. 4 nVersion, 4 nLocktime, 1 input count, 1 output count
751+ }
730752 for (const auto & recipient : vecSend)
731753 {
732754 CTxOut txout (recipient.nAmount , recipient.scriptPubKey );
@@ -743,6 +765,11 @@ bool CWallet::CreateTransactionInternal(
743765 }
744766 }
745767
768+ // Include the fee cost for outputs. Note this is only used for BnB right now
769+ if (!coin_selection_params.m_subtract_fee_outputs ) {
770+ coin_selection_params.tx_noinputs_size += ::GetSerializeSize (txout, PROTOCOL_VERSION);
771+ }
772+
746773 if (IsDust (txout, chain ().relayDustFee ()))
747774 {
748775 if (recipient.fSubtractFeeFromAmount && nFeeRet > 0 )
0 commit comments