Skip to content

Commit 1cf1c58

Browse files
kwvgUdjinM6
andcommitted
refactor: move selected coin and txin sorting to the end of the scope
Co-authored-by: UdjinM6 <[email protected]>
1 parent ab756ba commit 1cf1c58

File tree

2 files changed

+22
-34
lines changed

2 files changed

+22
-34
lines changed

src/wallet/spend.cpp

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -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;

src/wallet/spend.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,4 @@ class COutput
6161
}
6262
};
6363

64-
struct CompareInputCoinBIP69
65-
{
66-
inline bool operator()(const CInputCoin& a, const CInputCoin& b) const
67-
{
68-
// Note: CInputCoin-s are essentially inputs, their txouts are used for informational purposes only
69-
// that's why we use CompareInputBIP69 to sort them in a BIP69 compliant way.
70-
return CompareInputBIP69()(CTxIn(a.outpoint), CTxIn(b.outpoint));
71-
}
72-
};
73-
7464
#endif // BITCOIN_WALLET_SPEND_H

0 commit comments

Comments
 (0)