| 1499 | } |
| 1500 | |
| 1501 | util::Result<CreatedTransactionResult> FundTransaction(CWallet& wallet, const CMutableTransaction& tx, const std::vector<CRecipient>& vecSend, std::optional<unsigned int> change_pos, bool lockUnspents, CCoinControl coinControl) |
| 1502 | { |
| 1503 | // We want to make sure tx.vout is not used now that we are passing outputs as a vector of recipients. |
| 1504 | // This sets us up to remove tx completely in a future PR in favor of passing the inputs directly. |
| 1505 | assert(tx.vout.empty()); |
| 1506 | |
| 1507 | // Set the user desired locktime |
| 1508 | coinControl.m_locktime = tx.nLockTime; |
| 1509 | |
| 1510 | // Set the user desired version |
| 1511 | coinControl.m_version = tx.version; |
| 1512 | |
| 1513 | // Acquire the locks to prevent races to the new locked unspents between the |
| 1514 | // CreateTransaction call and LockCoin calls (when lockUnspents is true). |
| 1515 | LOCK(wallet.cs_wallet); |
| 1516 | |
| 1517 | // Fetch specified UTXOs from the UTXO set to get the scriptPubKeys and values of the outputs being selected |
| 1518 | // and to match with the given solving_data. Only used for non-wallet outputs. |
| 1519 | std::map<COutPoint, Coin> coins; |
| 1520 | for (const CTxIn& txin : tx.vin) { |
| 1521 | coins[txin.prevout]; // Create empty map entry keyed by prevout. |
| 1522 | } |
| 1523 | wallet.chain().findCoins(coins); |
| 1524 | |
| 1525 | for (const CTxIn& txin : tx.vin) { |
| 1526 | const auto& outPoint = txin.prevout; |
| 1527 | PreselectedInput& preset_txin = coinControl.Select(outPoint); |
| 1528 | if (!wallet.IsMine(outPoint)) { |
| 1529 | if (coins[outPoint].out.IsNull()) { |
| 1530 | return util::Error{_("Unable to find UTXO for external input")}; |
| 1531 | } |
| 1532 | |
| 1533 | // The input was not in the wallet, but is in the UTXO set, so select as external |
| 1534 | preset_txin.SetTxOut(coins[outPoint].out); |
| 1535 | } |
| 1536 | preset_txin.SetSequence(txin.nSequence); |
| 1537 | preset_txin.SetScriptSig(txin.scriptSig); |
| 1538 | preset_txin.SetScriptWitness(txin.scriptWitness); |
| 1539 | } |
| 1540 | |
| 1541 | auto res = CreateTransaction(wallet, vecSend, change_pos, coinControl, false); |
| 1542 | if (!res) { |
| 1543 | return res; |
| 1544 | } |
| 1545 | |
| 1546 | if (lockUnspents) { |
| 1547 | for (const CTxIn& txin : res->tx->vin) { |
| 1548 | wallet.LockCoin(txin.prevout, /*persist=*/false); |
| 1549 | } |
| 1550 | } |
| 1551 | |
| 1552 | return res; |
| 1553 | } |
| 1554 | } // namespace wallet |
nothing calls this directly
no test coverage detected