diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index f30106269..d02f306b6 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2501,6 +2501,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) " \"changeAddress\" (string, optional, default pool address) The bitcoin address to receive the change\n" " \"changePosition\" (numeric, optional, default random) The index of the change output\n" " \"includeWatching\" (boolean, optional, default false) Also select inputs which are watch only\n" + " \"lockUnspents\" (boolean, optional, default false) Lock selected unspent outputs\n" " }\n" " for backward compatibility: passing in a true instzead of an object will result in {\"includeWatching\":true}\n" "\nResult:\n" @@ -2526,6 +2527,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) CTxDestination changeAddress = CNoDestination(); int changePosition = -1; bool includeWatching = false; + bool lockUnspents = false; if (params.size() > 1) { if (params[1].type() == UniValue::VBOOL) { @@ -2537,7 +2539,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) UniValue options = params[1]; - RPCTypeCheckObj(options, boost::assign::map_list_of("changeAddress", UniValue::VSTR)("changePosition", UniValue::VNUM)("includeWatching", UniValue::VBOOL), true, true); + RPCTypeCheckObj(options, boost::assign::map_list_of("changeAddress", UniValue::VSTR)("changePosition", UniValue::VNUM)("includeWatching", UniValue::VBOOL)("lockUnspents", UniValue::VBOOL), true, true); if (options.exists("changeAddress")) { CBitcoinAddress address(options["changeAddress"].get_str()); @@ -2553,6 +2555,9 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) if (options.exists("includeWatching")) includeWatching = options["includeWatching"].get_bool(); + + if (options.exists("lockUnspents")) + lockUnspents = options["lockUnspents"].get_bool(); } } @@ -2571,7 +2576,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) CAmount nFee; string strFailReason; - if(!pwalletMain->FundTransaction(tx, nFee, changePosition, strFailReason, includeWatching, changeAddress)) + if(!pwalletMain->FundTransaction(tx, nFee, changePosition, strFailReason, includeWatching, lockUnspents, changeAddress)) throw JSONRPCError(RPC_INTERNAL_ERROR, strFailReason); UniValue result(UniValue::VOBJ); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 873fc2cba..4f8ca7487 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2401,7 +2401,7 @@ bool CWallet::SelectCoins(const CAmount& nTargetValue, set vecSend; @@ -2431,7 +2431,15 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nC BOOST_FOREACH(const CTxIn& txin, wtx.vin) { if (!coinControl.IsSelected(txin.prevout)) + { tx.vin.push_back(txin); + + if (lockUnspents) + { + LOCK2(cs_main, cs_wallet); + LockCoin(txin.prevout); + } + } } return true; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 8b28944e3..1479ed9f9 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -611,8 +611,8 @@ public: bool IsSpent(const uint256& hash, unsigned int n) const; bool IsLockedCoin(uint256 hash, unsigned int n) const; - void LockCoin(COutPoint& output); - void UnlockCoin(COutPoint& output); + void LockCoin(const COutPoint& output); + void UnlockCoin(const COutPoint& output); void UnlockAllCoins(); void ListLockedCoins(std::vector& vOutpts); @@ -684,7 +684,7 @@ public: * Insert additional inputs into the transaction by * calling CreateTransaction(); */ - bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, const CTxDestination& destChange = CNoDestination()); + bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, bool lockUnspents, const CTxDestination& destChange = CNoDestination()); /** * Create a new transaction paying the recipients with a set of coins