From e78bc45810c0834ad47cffcdfb52f0a57bfbba2d Mon Sep 17 00:00:00 2001 From: NicolasDorier Date: Fri, 7 Apr 2017 09:57:06 +0000 Subject: [PATCH] [Wallet] Decouple CInputCoin from CWalletTx --- src/wallet/feebumper.cpp | 2 +- src/wallet/wallet.cpp | 19 +++++++++---------- src/wallet/wallet.h | 35 +++++++++++++++++++++++++++++++++-- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/src/wallet/feebumper.cpp b/src/wallet/feebumper.cpp index 7201d17b07..6b030935f3 100644 --- a/src/wallet/feebumper.cpp +++ b/src/wallet/feebumper.cpp @@ -30,7 +30,7 @@ int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *pWal for (auto& input : tx.vin) { const auto mi = pWallet->mapWallet.find(input.prevout.hash); assert(mi != pWallet->mapWallet.end() && input.prevout.n < mi->second.tx->vout.size()); - vCoins.emplace_back(&(mi->second), input.prevout.n); + vCoins.emplace_back(CInputCoin(&(mi->second), input.prevout.n)); } if (!pWallet->DummySignTx(txNew, vCoins)) { // This should never happen, because IsAllFromMe(ISMINE_SPENDABLE) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 982293acae..2b12ece8dc 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2087,7 +2087,6 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, const int nConfMin // List of values less than target std::pair coinLowestLarger; coinLowestLarger.first = std::numeric_limits::max(); - coinLowestLarger.second.first = NULL; std::vector > vValue; CAmount nTotalLower = 0; @@ -2109,7 +2108,7 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, const int nConfMin int i = output.i; CAmount n = pcoin->tx->vout[i].nValue; - std::pair coin = std::make_pair(n,std::make_pair(pcoin, i)); + std::pair coin = std::make_pair(n, CInputCoin(pcoin, i)); if (n == nTargetValue) { @@ -2140,7 +2139,7 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, const int nConfMin if (nTotalLower < nTargetValue) { - if (coinLowestLarger.second.first == NULL) + if (coinLowestLarger.second.IsNull()) return false; setCoinsRet.insert(coinLowestLarger.second); nValueRet += coinLowestLarger.first; @@ -2159,7 +2158,7 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, const int nConfMin // If we have a bigger coin and (either the stochastic approximation didn't find a good solution, // or the next bigger coin is closer), return the bigger coin - if (coinLowestLarger.second.first && + if (coinLowestLarger.second.IsNull() && ((nBest != nTargetValue && nBest < nTargetValue + MIN_CHANGE) || coinLowestLarger.first <= nBest)) { setCoinsRet.insert(coinLowestLarger.second); @@ -2199,7 +2198,7 @@ bool CWallet::SelectCoins(const std::vector& vAvailableCoins, const CAm if (!out.fSpendable) continue; nValueRet += out.tx->tx->vout[out.i].nValue; - setCoinsRet.insert(std::make_pair(out.tx, out.i)); + setCoinsRet.insert(CInputCoin(out.tx, out.i)); } return (nValueRet >= nTargetValue); } @@ -2221,7 +2220,7 @@ bool CWallet::SelectCoins(const std::vector& vAvailableCoins, const CAm if (pcoin->tx->vout.size() <= outpoint.n) return false; nValueFromPresetInputs += pcoin->tx->vout[outpoint.n].nValue; - setPresetCoins.insert(std::make_pair(pcoin, outpoint.n)); + setPresetCoins.insert(CInputCoin(pcoin, outpoint.n)); } else return false; // TODO: Allow non-wallet inputs } @@ -2229,7 +2228,7 @@ bool CWallet::SelectCoins(const std::vector& vAvailableCoins, const CAm // remove preset inputs from vCoins for (std::vector::iterator it = vCoins.begin(); it != vCoins.end() && coinControl && coinControl->HasSelected();) { - if (setPresetCoins.count(std::make_pair(it->tx, it->i))) + if (setPresetCoins.count(CInputCoin(it->tx, it->i))) it = vCoins.erase(it); else ++it; @@ -2554,7 +2553,7 @@ bool CWallet::CreateTransaction(const std::vector& vecSend, CWalletT // behavior." bool rbf = coinControl ? coinControl->signalRbf : fWalletRbf; for (const auto& coin : setCoins) - txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second,CScript(), + txNew.vin.push_back(CTxIn(coin.outpoint,CScript(), std::numeric_limits::max() - (rbf ? 2 : 1))); // Fill in dummy signatures for fee calculation. @@ -2637,10 +2636,10 @@ bool CWallet::CreateTransaction(const std::vector& vecSend, CWalletT int nIn = 0; for (const auto& coin : setCoins) { - const CScript& scriptPubKey = coin.first->tx->vout[coin.second].scriptPubKey; + const CScript& scriptPubKey = coin.txout.scriptPubKey; SignatureData sigdata; - if (!ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, coin.first->tx->vout[coin.second].nValue, SIGHASH_ALL), scriptPubKey, sigdata)) + if (!ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, coin.txout.nValue, SIGHASH_ALL), scriptPubKey, sigdata)) { strFailReason = _("Signing transaction failed"); return false; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index a882cec778..d43bd4b590 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -475,7 +475,38 @@ public: }; -using CInputCoin = std::pair; +class CInputCoin { +public: + CInputCoin() + { + } + CInputCoin(const CWalletTx* walletTx, unsigned int i) + { + if (walletTx != nullptr && i < walletTx->tx->vout.size()) + { + outpoint = COutPoint(walletTx->GetHash(), i); + txout = walletTx->tx->vout[i]; + } + } + bool IsNull() const + { + return outpoint.IsNull() && txout.IsNull(); + } + COutPoint outpoint; + CTxOut txout; + + bool operator<(const CInputCoin& rhs) const { + return outpoint < rhs.outpoint; + } + + bool operator!=(const CInputCoin& rhs) const { + return outpoint != rhs.outpoint; + } + + bool operator==(const CInputCoin& rhs) const { + return outpoint == rhs.outpoint; + } +}; class COutput { @@ -1132,7 +1163,7 @@ bool CWallet::DummySignTx(CMutableTransaction &txNew, const ContainerType &coins int nIn = 0; for (const auto& coin : coins) { - const CScript& scriptPubKey = coin.first->tx->vout[coin.second].scriptPubKey; + const CScript& scriptPubKey = coin.txout.scriptPubKey; SignatureData sigdata; if (!ProduceSignature(DummySignatureCreator(this), scriptPubKey, sigdata))