diff options
| author | Wladimir J. van der Laan <[email protected]> | 2016-04-15 16:23:16 +0200 |
|---|---|---|
| committer | Wladimir J. van der Laan <[email protected]> | 2016-04-15 16:24:02 +0200 |
| commit | be14ca5e8c0f0e8cd8ef511ccb9c41f245d62fbf (patch) | |
| tree | dc4ecb77376030b326930abc247133766aee5e9b /src/wallet/wallet.cpp | |
| parent | Merge #7870: [contrib] Add MarcoFalke key and move all keys to contrib/gitian... (diff) | |
| parent | Add lockUnspents option to fundrawtransaction (diff) | |
| download | discoin-be14ca5e8c0f0e8cd8ef511ccb9c41f245d62fbf.tar.xz discoin-be14ca5e8c0f0e8cd8ef511ccb9c41f245d62fbf.zip | |
Merge #7518: Add multiple options to fundrawtransaction
f2d0944 Add lockUnspents option to fundrawtransaction (João Barbosa)
af4fe7f Add change options to fundrawtransaction (João Barbosa)
41e835d Add strict flag to RPCTypeCheckObj (João Barbosa)
Diffstat (limited to 'src/wallet/wallet.cpp')
| -rw-r--r-- | src/wallet/wallet.cpp | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index e8c946671..8161c659a 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1932,7 +1932,7 @@ bool CWallet::SelectCoins(const vector<COutput>& vAvailableCoins, const CAmount& return res; } -bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount &nFeeRet, int& nChangePosRet, std::string& strFailReason, bool includeWatching) +bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, bool lockUnspents, const CTxDestination& destChange) { vector<CRecipient> vecSend; @@ -1944,6 +1944,7 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount &nFeeRet, int& nC } CCoinControl coinControl; + coinControl.destChange = destChange; coinControl.fAllowOtherInputs = true; coinControl.fAllowWatchOnly = includeWatching; BOOST_FOREACH(const CTxIn& txin, tx.vin) @@ -1951,26 +1952,35 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount &nFeeRet, int& nC CReserveKey reservekey(this); CWalletTx wtx; - if (!CreateTransaction(vecSend, wtx, reservekey, nFeeRet, nChangePosRet, strFailReason, &coinControl, false)) + if (!CreateTransaction(vecSend, wtx, reservekey, nFeeRet, nChangePosInOut, strFailReason, &coinControl, false)) return false; - if (nChangePosRet != -1) - tx.vout.insert(tx.vout.begin() + nChangePosRet, wtx.vout[nChangePosRet]); + if (nChangePosInOut != -1) + tx.vout.insert(tx.vout.begin() + nChangePosInOut, wtx.vout[nChangePosInOut]); // Add new txins (keeping original txin scriptSig/order) 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; } bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, - int& nChangePosRet, std::string& strFailReason, const CCoinControl* coinControl, bool sign) + int& nChangePosInOut, std::string& strFailReason, const CCoinControl* coinControl, bool sign) { CAmount nValue = 0; + int nChangePosRequest = nChangePosInOut; unsigned int nSubtractFeeFromAmount = 0; BOOST_FOREACH (const CRecipient& recipient, vecSend) { @@ -2036,10 +2046,10 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt // Start with no fee and loop until there is enough fee while (true) { + nChangePosInOut = nChangePosRequest; txNew.vin.clear(); txNew.vout.clear(); wtxNew.fFromMe = true; - nChangePosRet = -1; bool fFirst = true; CAmount nValueToSelect = nValue; @@ -2159,14 +2169,24 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt // add the dust to the fee. if (newTxOut.IsDust(::minRelayTxFee)) { + nChangePosInOut = -1; nFeeRet += nChange; reservekey.ReturnKey(); } else { - // Insert change txn at random position: - nChangePosRet = GetRandInt(txNew.vout.size()+1); - vector<CTxOut>::iterator position = txNew.vout.begin()+nChangePosRet; + if (nChangePosInOut == -1) + { + // Insert change txn at random position: + nChangePosInOut = GetRandInt(txNew.vout.size()+1); + } + else if (nChangePosInOut > txNew.vout.size()) + { + strFailReason = _("Change index out of range"); + return false; + } + + vector<CTxOut>::iterator position = txNew.vout.begin()+nChangePosInOut; txNew.vout.insert(position, newTxOut); } } @@ -2842,13 +2862,13 @@ void CWallet::GetScriptForMining(boost::shared_ptr<CReserveScript> &script) script->reserveScript = CScript() << ToByteVector(pubkey) << OP_CHECKSIG; } -void CWallet::LockCoin(COutPoint& output) +void CWallet::LockCoin(const COutPoint& output) { AssertLockHeld(cs_wallet); // setLockedCoins setLockedCoins.insert(output); } -void CWallet::UnlockCoin(COutPoint& output) +void CWallet::UnlockCoin(const COutPoint& output) { AssertLockHeld(cs_wallet); // setLockedCoins setLockedCoins.erase(output); |