| 3194 | } |
| 3195 | |
| 3196 | bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, bool overrideEstimatedFeeRate, int& nChangePosInOut, std::string& strFailReason, |
| 3197 | bool lockUnspents, const std::set<int>& setSubtractFeeFromOutputs, CCoinControl* coinControl) |
| 3198 | { |
| 3199 | //assert(coinControl != nullptr); |
| 3200 | std::vector<CRecipient> vecSend; |
| 3201 | |
| 3202 | // Turn the txout set into a CRecipient vector. |
| 3203 | for (size_t idx = 0; idx < tx.vout.size(); idx++) { |
| 3204 | const CTxOut& txOut = tx.vout[idx]; |
| 3205 | CRecipient recipient = {txOut.scriptPubKey, txOut.nValue, setSubtractFeeFromOutputs.count(idx) == 1}; |
| 3206 | vecSend.push_back(recipient); |
| 3207 | } |
| 3208 | |
| 3209 | coinControl->fAllowOtherInputs = true; |
| 3210 | coinControl->fOverrideFeeRate = overrideEstimatedFeeRate; |
| 3211 | |
| 3212 | for (const CTxIn& txin : tx.vin) { |
| 3213 | coinControl->Select(txin.prevout); |
| 3214 | } |
| 3215 | |
| 3216 | // Acquire the locks to prevent races to the new locked unspents between the |
| 3217 | // CreateTransaction call and LockCoin calls (when lockUnspents is true). |
| 3218 | LOCK2(cs_main, cs_wallet); |
| 3219 | |
| 3220 | CReserveKey reservekey(this); |
| 3221 | CWalletTx wtx; |
| 3222 | if (!CreateTransaction(vecSend, wtx, reservekey, nFeeRet, nChangePosInOut, strFailReason, coinControl, ALL_COINS, false, 0, 0, false)) { |
| 3223 | return false; |
| 3224 | } |
| 3225 | |
| 3226 | if (nChangePosInOut != -1) { |
| 3227 | tx.vout.insert(tx.vout.begin() + nChangePosInOut, wtx.vout[nChangePosInOut]); |
| 3228 | |
| 3229 | // Copy output sizes from new transaction; they may have had the fee subtracted from them |
| 3230 | for (unsigned int idx = 0; idx < tx.vout.size(); idx++) |
| 3231 | tx.vout[idx].nValue = wtx.vout[idx].nValue; |
| 3232 | |
| 3233 | // We don't have the normal Create/Commit cycle, and don't want to risk |
| 3234 | // reusing change, so just remove the key from the keypool here. |
| 3235 | reservekey.KeepKey(); |
| 3236 | } |
| 3237 | |
| 3238 | // Copy output sizes from new transaction; they may have had the fee |
| 3239 | // subtracted from them. |
| 3240 | for (unsigned int idx = 0; idx < tx.vout.size(); idx++) { |
| 3241 | tx.vout[idx].nValue = wtx.vout[idx].nValue; |
| 3242 | } |
| 3243 | |
| 3244 | // Add new txins while keeping original txin scriptSig/order. |
| 3245 | for (const CTxIn& txin : wtx.vin) { |
| 3246 | if (!coinControl->IsSelected(txin.prevout.hash, txin.prevout.n)) { |
| 3247 | tx.vin.push_back(txin); |
| 3248 | |
| 3249 | if (lockUnspents) { |
| 3250 | LockCoin(txin.prevout); |
| 3251 | } |
| 3252 | } |
| 3253 | } |
no test coverage detected