@@ -618,6 +618,7 @@ bool CWallet::CreateTransactionInternal(
618618 CAmount nValue = 0 ;
619619 ReserveDestination reservedest (this );
620620 int nChangePosRequest = nChangePosInOut;
621+ const bool sort_bip69{nChangePosRequest == -1 };
621622 unsigned int nSubtractFeeFromAmount = 0 ;
622623 for (const auto & recipient : vecSend)
623624 {
@@ -659,7 +660,7 @@ bool CWallet::CreateTransactionInternal(
659660
660661 int nBytes{0 };
661662 {
662- std::vector <CInputCoin> vecCoins ;
663+ std::set <CInputCoin> setCoins ;
663664 LOCK (cs_wallet);
664665 txNew.nLockTime = GetLocktimeForNewTransaction (chain (), GetLastBlockHash (), GetLastBlockHeight ());
665666 {
@@ -759,8 +760,8 @@ bool CWallet::CreateTransactionInternal(
759760 bool bnb_used = false ;
760761 if (pick_new_inputs) {
761762 nValueIn = 0 ;
762- std::set<CInputCoin> setCoinsTmp ;
763- if (!SelectCoins (vAvailableCoins, nValueToSelect, setCoinsTmp , nValueIn, coin_control, coin_selection_params, bnb_used)) {
763+ setCoins. clear () ;
764+ if (!SelectCoins (vAvailableCoins, nValueToSelect, setCoins , nValueIn, coin_control, coin_selection_params, bnb_used)) {
764765 if (coin_control.nCoinType == CoinType::ONLY_NONDENOMINATED) {
765766 error = _ (" Unable to locate enough non-denominated funds for this transaction." );
766767 } else if (coin_control.nCoinType == CoinType::ONLY_FULLY_MIXED) {
@@ -771,16 +772,13 @@ bool CWallet::CreateTransactionInternal(
771772 }
772773 return false ;
773774 }
774- vecCoins.assign (setCoinsTmp.begin (), setCoinsTmp.end ());
775775 }
776776
777- // Fill vin
777+ // Dummy fill vin for maximum size estimation
778778 //
779- // Note how the sequence number is set to max()-1 so that the
780- // nLockTime set above actually works.
781779 txNew.vin .clear ();
782- for (const auto & coin : vecCoins ) {
783- txNew.vin .emplace_back ( coin.outpoint , CScript (), CTxIn::SEQUENCE_FINAL - 1 );
780+ for (const auto & coin : setCoins ) {
781+ txNew.vin .push_back ( CTxIn ( coin.outpoint , CScript ()) );
784782 }
785783
786784 auto calculateFee = [&](CAmount& nFee) EXCLUSIVE_LOCKS_REQUIRED (cs_wallet) -> bool {
@@ -889,24 +887,13 @@ bool CWallet::CreateTransactionInternal(
889887 continue ;
890888 }
891889
892- // If no specific change position was requested, apply BIP69
893- if (nChangePosRequest == -1 ) {
894- std::sort (vecCoins.begin (), vecCoins.end (), CompareInputCoinBIP69 ());
895- std::sort (txNew.vin .begin (), txNew.vin .end (), CompareInputBIP69 ());
890+ if (sort_bip69) {
896891 std::sort (txNew.vout .begin (), txNew.vout .end (), CompareOutputBIP69 ());
897892
898893 // If there was a change output added before, we must update its position now
899- if (nChangePosInOut != -1 ) {
900- int i = 0 ;
901- for (const CTxOut& txOut : txNew.vout )
902- {
903- if (txOut == newTxOut)
904- {
905- nChangePosInOut = i;
906- break ;
907- }
908- i++;
909- }
894+ if (const auto it = std::find (txNew.vout .begin (), txNew.vout .end (), newTxOut);
895+ it != txNew.vout .end () && nChangePosInOut != -1 ) {
896+ nChangePosInOut = std::distance (txNew.vout .begin (), it);
910897 }
911898 }
912899
@@ -949,6 +936,17 @@ bool CWallet::CreateTransactionInternal(
949936 // Make sure change position was updated one way or another
950937 assert (nChangePosInOut != std::numeric_limits<int >::max ());
951938
939+ // Fill in final vin and shuffle/sort it
940+ txNew.vin .clear ();
941+
942+ // Note how the sequence number is set to non-maxint so that
943+ // the nLockTime set above actually works.
944+ const uint32_t nSequence = CTxIn::SEQUENCE_FINAL - 1 ;
945+ for (const auto & coin : setCoins) {
946+ txNew.vin .push_back (CTxIn (coin.outpoint , CScript (), nSequence));
947+ }
948+ if (sort_bip69) { std::sort (txNew.vin .begin (), txNew.vin .end (), CompareInputBIP69 ()); }
949+
952950 if (sign && !SignTransaction (txNew)) {
953951 error = _ (" Signing transaction failed" );
954952 return false ;
0 commit comments