Coin Control Features
This commit is contained in:
committed by
Wladimir J. van der Laan
parent
8dfd8c62dc
commit
6a86c24db1
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user