From 6a86c24db146d9ca5d1d5c83099d935c3feb63bb Mon Sep 17 00:00:00 2001 From: Cozz Lovan Date: Mon, 12 Aug 2013 17:03:03 +0200 Subject: Coin Control Features --- src/qt/walletmodel.cpp | 94 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 88 insertions(+), 6 deletions(-) (limited to 'src/qt/walletmodel.cpp') diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index b1d770e1a7..2470af41a0 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -47,8 +47,19 @@ WalletModel::~WalletModel() unsubscribeFromCoreSignals(); } -qint64 WalletModel::getBalance() const +qint64 WalletModel::getBalance(const CCoinControl *coinControl) const { + if (coinControl) + { + qint64 nBalance = 0; + std::vector vCoins; + wallet->AvailableCoins(vCoins, true, coinControl); + BOOST_FOREACH(const COutput& out, vCoins) + nBalance += out.tx->vout[out.i].nValue; + + return nBalance; + } + return wallet->GetBalance(); } @@ -136,7 +147,7 @@ bool WalletModel::validateAddress(const QString &address) return addressParsed.IsValid(); } -WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransaction &transaction) +WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl) { qint64 total = 0; QList recipients = transaction.getRecipients(); @@ -197,12 +208,14 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact return DuplicateAddress; } - if(total > getBalance()) + qint64 nBalance = getBalance(coinControl); + + if(total > nBalance) { return AmountExceedsBalance; } - if((total + nTransactionFee) > getBalance()) + if((total + nTransactionFee) > nBalance) { transaction.setTransactionFee(nTransactionFee); return SendCoinsReturn(AmountWithFeeExceedsBalance); @@ -217,12 +230,12 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact CWalletTx *newTx = transaction.getTransaction(); CReserveKey *keyChange = transaction.getPossibleKeyChange(); - bool fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, nFeeRequired, strFailReason); + bool fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, nFeeRequired, strFailReason, coinControl); transaction.setTransactionFee(nFeeRequired); if(!fCreated) { - if((total + nFeeRequired) > wallet->GetBalance()) + if((total + nFeeRequired) > nBalance) { return SendCoinsReturn(AmountWithFeeExceedsBalance); } @@ -458,3 +471,72 @@ void WalletModel::UnlockContext::CopyFrom(const UnlockContext& rhs) *this = rhs; rhs.relock = false; } + +bool WalletModel::getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const +{ + return wallet->GetPubKey(address, vchPubKeyOut); +} + +// returns a list of COutputs from COutPoints +void WalletModel::getOutputs(const std::vector& vOutpoints, std::vector& vOutputs) +{ + BOOST_FOREACH(const COutPoint& outpoint, vOutpoints) + { + if (!wallet->mapWallet.count(outpoint.hash)) continue; + COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, wallet->mapWallet[outpoint.hash].GetDepthInMainChain()); + vOutputs.push_back(out); + } +} + +// AvailableCoins + LockedCoins grouped by wallet address (put change in one group with wallet address) +void WalletModel::listCoins(std::map >& mapCoins) const +{ + std::vector vCoins; + wallet->AvailableCoins(vCoins); + + std::vector vLockedCoins; + wallet->ListLockedCoins(vLockedCoins); + + // add locked coins + BOOST_FOREACH(const COutPoint& outpoint, vLockedCoins) + { + if (!wallet->mapWallet.count(outpoint.hash)) continue; + COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, wallet->mapWallet[outpoint.hash].GetDepthInMainChain()); + vCoins.push_back(out); + } + + BOOST_FOREACH(const COutput& out, vCoins) + { + COutput cout = out; + + while (wallet->IsChange(cout.tx->vout[cout.i]) && cout.tx->vin.size() > 0 && wallet->IsMine(cout.tx->vin[0])) + { + if (!wallet->mapWallet.count(cout.tx->vin[0].prevout.hash)) break; + cout = COutput(&wallet->mapWallet[cout.tx->vin[0].prevout.hash], cout.tx->vin[0].prevout.n, 0); + } + + CTxDestination address; + if(!ExtractDestination(cout.tx->vout[cout.i].scriptPubKey, address)) continue; + mapCoins[CBitcoinAddress(address).ToString().c_str()].push_back(out); + } +} + +bool WalletModel::isLockedCoin(uint256 hash, unsigned int n) const +{ + return wallet->IsLockedCoin(hash, n); +} + +void WalletModel::lockCoin(COutPoint& output) +{ + wallet->LockCoin(output); +} + +void WalletModel::unlockCoin(COutPoint& output) +{ + wallet->UnlockCoin(output); +} + +void WalletModel::listLockedCoins(std::vector& vOutpts) +{ + wallet->ListLockedCoins(vOutpts); +} -- cgit v1.2.3