| 2579 | } |
| 2580 | |
| 2581 | bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, bool lockUnspents, const std::set<int>& setSubtractFeeFromOutputs, CCoinControl coinControl) |
| 2582 | { |
| 2583 | std::vector<CRecipient> vecSend; |
| 2584 | |
| 2585 | // Turn the txout set into a CRecipient vector. |
| 2586 | for (size_t idx = 0; idx < tx.vout.size(); idx++) { |
| 2587 | const CTxOut& txOut = tx.vout[idx]; |
| 2588 | CRecipient recipient = {txOut.scriptPubKey, txOut.nValue, setSubtractFeeFromOutputs.count(idx) == 1}; |
| 2589 | vecSend.push_back(recipient); |
| 2590 | } |
| 2591 | |
| 2592 | coinControl.fAllowOtherInputs = true; |
| 2593 | |
| 2594 | for (const CTxIn& txin : tx.vin) { |
| 2595 | coinControl.Select(txin.prevout); |
| 2596 | } |
| 2597 | |
| 2598 | // Acquire the locks to prevent races to the new locked unspents between the |
| 2599 | // CreateTransaction call and LockCoin calls (when lockUnspents is true). |
| 2600 | LOCK2(cs_main, cs_wallet); |
| 2601 | |
| 2602 | CReserveKey reservekey(this); |
| 2603 | CTransactionRef tx_new; |
| 2604 | bool no_forkid = !IsBTGHardForkEnabledForCurrentBlock(Params().GetConsensus()); |
| 2605 | if (!CreateTransaction(vecSend, tx_new, reservekey, nFeeRet, nChangePosInOut, no_forkid, strFailReason, coinControl, false)) { |
| 2606 | return false; |
| 2607 | } |
| 2608 | |
| 2609 | if (nChangePosInOut != -1) { |
| 2610 | tx.vout.insert(tx.vout.begin() + nChangePosInOut, tx_new->vout[nChangePosInOut]); |
| 2611 | // We don't have the normal Create/Commit cycle, and don't want to risk |
| 2612 | // reusing change, so just remove the key from the keypool here. |
| 2613 | reservekey.KeepKey(); |
| 2614 | } |
| 2615 | |
| 2616 | // Copy output sizes from new transaction; they may have had the fee |
| 2617 | // subtracted from them. |
| 2618 | for (unsigned int idx = 0; idx < tx.vout.size(); idx++) { |
| 2619 | tx.vout[idx].nValue = tx_new->vout[idx].nValue; |
| 2620 | } |
| 2621 | |
| 2622 | // Add new txins while keeping original txin scriptSig/order. |
| 2623 | for (const CTxIn& txin : tx_new->vin) { |
| 2624 | if (!coinControl.IsSelected(txin.prevout)) { |
| 2625 | tx.vin.push_back(txin); |
| 2626 | |
| 2627 | if (lockUnspents) { |
| 2628 | LockCoin(txin.prevout); |
| 2629 | } |
| 2630 | } |
| 2631 | } |
| 2632 | |
| 2633 | return true; |
| 2634 | } |
| 2635 | |
| 2636 | OutputType CWallet::TransactionChangeType(OutputType change_type, const std::vector<CRecipient>& vecSend) |
| 2637 | { |
no test coverage detected