Coin Control Features

This commit is contained in:
Cozz Lovan
2013-08-12 17:03:03 +02:00
committed by Wladimir J. van der Laan
parent 8dfd8c62dc
commit 6a86c24db1
23 changed files with 2558 additions and 43 deletions

View File

@@ -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<COutput> 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<SendCoinsRecipient> 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<COutPoint>& vOutpoints, std::vector<COutput>& 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<QString, std::vector<COutput> >& mapCoins) const
{
std::vector<COutput> vCoins;
wallet->AvailableCoins(vCoins);
std::vector<COutPoint> 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<COutPoint>& vOutpts)
{
wallet->ListLockedCoins(vOutpts);
}