Changeset View
Changeset View
Standalone View
Standalone View
src/qt/walletmodel.cpp
Show First 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | WalletModel::WalletModel(const PlatformStyle *platformStyle, CWallet *_wallet, | ||||
subscribeToCoreSignals(); | subscribeToCoreSignals(); | ||||
} | } | ||||
WalletModel::~WalletModel() { | WalletModel::~WalletModel() { | ||||
unsubscribeFromCoreSignals(); | unsubscribeFromCoreSignals(); | ||||
} | } | ||||
CAmount WalletModel::getBalance(const CCoinControl *coinControl) const { | Amount WalletModel::getBalance(const CCoinControl *coinControl) const { | ||||
if (coinControl) { | if (coinControl) { | ||||
Amount nBalance(0); | Amount nBalance(0); | ||||
std::vector<COutput> vCoins; | std::vector<COutput> vCoins; | ||||
wallet->AvailableCoins(vCoins, true, coinControl); | wallet->AvailableCoins(vCoins, true, coinControl); | ||||
for (const COutput &out : vCoins) { | for (const COutput &out : vCoins) { | ||||
if (out.fSpendable) nBalance += out.tx->tx->vout[out.i].nValue; | if (out.fSpendable) nBalance += out.tx->tx->vout[out.i].nValue; | ||||
} | } | ||||
return nBalance.GetSatoshis(); | return nBalance; | ||||
} | } | ||||
return wallet->GetBalance().GetSatoshis(); | return wallet->GetBalance(); | ||||
} | } | ||||
CAmount WalletModel::getUnconfirmedBalance() const { | Amount WalletModel::getUnconfirmedBalance() const { | ||||
return wallet->GetUnconfirmedBalance().GetSatoshis(); | return wallet->GetUnconfirmedBalance(); | ||||
} | } | ||||
CAmount WalletModel::getImmatureBalance() const { | Amount WalletModel::getImmatureBalance() const { | ||||
return wallet->GetImmatureBalance().GetSatoshis(); | return wallet->GetImmatureBalance(); | ||||
} | } | ||||
bool WalletModel::haveWatchOnly() const { | bool WalletModel::haveWatchOnly() const { | ||||
return fHaveWatchOnly; | return fHaveWatchOnly; | ||||
} | } | ||||
CAmount WalletModel::getWatchBalance() const { | Amount WalletModel::getWatchBalance() const { | ||||
return wallet->GetWatchOnlyBalance().GetSatoshis(); | return wallet->GetWatchOnlyBalance(); | ||||
} | } | ||||
CAmount WalletModel::getWatchUnconfirmedBalance() const { | Amount WalletModel::getWatchUnconfirmedBalance() const { | ||||
return wallet->GetUnconfirmedWatchOnlyBalance().GetSatoshis(); | return wallet->GetUnconfirmedWatchOnlyBalance(); | ||||
} | } | ||||
CAmount WalletModel::getWatchImmatureBalance() const { | Amount WalletModel::getWatchImmatureBalance() const { | ||||
return wallet->GetImmatureWatchOnlyBalance().GetSatoshis(); | return wallet->GetImmatureWatchOnlyBalance(); | ||||
} | } | ||||
void WalletModel::updateStatus() { | void WalletModel::updateStatus() { | ||||
EncryptionStatus newEncryptionStatus = getEncryptionStatus(); | EncryptionStatus newEncryptionStatus = getEncryptionStatus(); | ||||
if (cachedEncryptionStatus != newEncryptionStatus) | if (cachedEncryptionStatus != newEncryptionStatus) | ||||
Q_EMIT encryptionStatusChanged(newEncryptionStatus); | Q_EMIT encryptionStatusChanged(newEncryptionStatus); | ||||
} | } | ||||
Show All 14 Lines | if (fForceCheckBalanceChanged || chainActive.Height() != cachedNumBlocks) { | ||||
cachedNumBlocks = chainActive.Height(); | cachedNumBlocks = chainActive.Height(); | ||||
checkBalanceChanged(); | checkBalanceChanged(); | ||||
if (transactionTableModel) transactionTableModel->updateConfirmations(); | if (transactionTableModel) transactionTableModel->updateConfirmations(); | ||||
} | } | ||||
} | } | ||||
void WalletModel::checkBalanceChanged() { | void WalletModel::checkBalanceChanged() { | ||||
CAmount newBalance = getBalance(); | Amount newBalance = getBalance(); | ||||
CAmount newUnconfirmedBalance = getUnconfirmedBalance(); | Amount newUnconfirmedBalance = getUnconfirmedBalance(); | ||||
CAmount newImmatureBalance = getImmatureBalance(); | Amount newImmatureBalance = getImmatureBalance(); | ||||
CAmount newWatchOnlyBalance = 0; | Amount newWatchOnlyBalance = 0; | ||||
CAmount newWatchUnconfBalance = 0; | Amount newWatchUnconfBalance = 0; | ||||
CAmount newWatchImmatureBalance = 0; | Amount newWatchImmatureBalance = 0; | ||||
if (haveWatchOnly()) { | if (haveWatchOnly()) { | ||||
newWatchOnlyBalance = getWatchBalance(); | newWatchOnlyBalance = getWatchBalance(); | ||||
newWatchUnconfBalance = getWatchUnconfirmedBalance(); | newWatchUnconfBalance = getWatchUnconfirmedBalance(); | ||||
newWatchImmatureBalance = getWatchImmatureBalance(); | newWatchImmatureBalance = getWatchImmatureBalance(); | ||||
} | } | ||||
if (cachedBalance != newBalance || | if (cachedBalance != newBalance || | ||||
cachedUnconfirmedBalance != newUnconfirmedBalance || | cachedUnconfirmedBalance != newUnconfirmedBalance || | ||||
Show All 32 Lines | |||||
bool WalletModel::validateAddress(const QString &address) { | bool WalletModel::validateAddress(const QString &address) { | ||||
return IsValidDestinationString(address.toStdString()); | return IsValidDestinationString(address.toStdString()); | ||||
} | } | ||||
WalletModel::SendCoinsReturn | WalletModel::SendCoinsReturn | ||||
WalletModel::prepareTransaction(WalletModelTransaction &transaction, | WalletModel::prepareTransaction(WalletModelTransaction &transaction, | ||||
const CCoinControl *coinControl) { | const CCoinControl *coinControl) { | ||||
CAmount total = 0; | Amount total = 0; | ||||
bool fSubtractFeeFromAmount = false; | bool fSubtractFeeFromAmount = false; | ||||
QList<SendCoinsRecipient> recipients = transaction.getRecipients(); | QList<SendCoinsRecipient> recipients = transaction.getRecipients(); | ||||
std::vector<CRecipient> vecSend; | std::vector<CRecipient> vecSend; | ||||
if (recipients.empty()) { | if (recipients.empty()) { | ||||
return OK; | return OK; | ||||
} | } | ||||
// Used to detect duplicates | // Used to detect duplicates | ||||
QSet<QString> setAddress; | QSet<QString> setAddress; | ||||
int nAddresses = 0; | int nAddresses = 0; | ||||
// Pre-check input data for validity | // Pre-check input data for validity | ||||
for (const SendCoinsRecipient &rcp : recipients) { | for (const SendCoinsRecipient &rcp : recipients) { | ||||
if (rcp.fSubtractFeeFromAmount) fSubtractFeeFromAmount = true; | if (rcp.fSubtractFeeFromAmount) fSubtractFeeFromAmount = true; | ||||
// PaymentRequest... | // PaymentRequest... | ||||
if (rcp.paymentRequest.IsInitialized()) { | if (rcp.paymentRequest.IsInitialized()) { | ||||
CAmount subtotal = 0; | Amount subtotal = 0; | ||||
const payments::PaymentDetails &details = | const payments::PaymentDetails &details = | ||||
rcp.paymentRequest.getDetails(); | rcp.paymentRequest.getDetails(); | ||||
for (int i = 0; i < details.outputs_size(); i++) { | for (int i = 0; i < details.outputs_size(); i++) { | ||||
const payments::Output &out = details.outputs(i); | const payments::Output &out = details.outputs(i); | ||||
if (out.amount() <= 0) continue; | if (out.amount() <= 0) continue; | ||||
subtotal += out.amount(); | subtotal += out.amount(); | ||||
const uint8_t *scriptStr = (const uint8_t *)out.script().data(); | const uint8_t *scriptStr = (const uint8_t *)out.script().data(); | ||||
CScript scriptPubKey(scriptStr, | CScript scriptPubKey(scriptStr, | ||||
scriptStr + out.script().size()); | scriptStr + out.script().size()); | ||||
CAmount nAmount = out.amount(); | Amount nAmount = out.amount(); | ||||
CRecipient recipient = {scriptPubKey, Amount(nAmount), | CRecipient recipient = {scriptPubKey, Amount(nAmount), | ||||
rcp.fSubtractFeeFromAmount}; | rcp.fSubtractFeeFromAmount}; | ||||
vecSend.push_back(recipient); | vecSend.push_back(recipient); | ||||
} | } | ||||
if (subtotal <= 0) { | if (subtotal <= 0) { | ||||
return InvalidAmount; | return InvalidAmount; | ||||
} | } | ||||
total += subtotal; | total += subtotal; | ||||
Show All 15 Lines | for (const SendCoinsRecipient &rcp : recipients) { | ||||
total += rcp.amount; | total += rcp.amount; | ||||
} | } | ||||
} | } | ||||
if (setAddress.size() != nAddresses) { | if (setAddress.size() != nAddresses) { | ||||
return DuplicateAddress; | return DuplicateAddress; | ||||
} | } | ||||
CAmount nBalance = getBalance(coinControl); | Amount nBalance = getBalance(coinControl); | ||||
if (total > nBalance) { | if (total > nBalance) { | ||||
return AmountExceedsBalance; | return AmountExceedsBalance; | ||||
} | } | ||||
{ | { | ||||
LOCK2(cs_main, wallet->cs_wallet); | LOCK2(cs_main, wallet->cs_wallet); | ||||
transaction.newPossibleKeyChange(wallet); | transaction.newPossibleKeyChange(wallet); | ||||
Amount nFeeRequired(0); | Amount nFeeRequired(0); | ||||
int nChangePosRet = -1; | int nChangePosRet = -1; | ||||
std::string strFailReason; | std::string strFailReason; | ||||
CWalletTx *newTx = transaction.getTransaction(); | CWalletTx *newTx = transaction.getTransaction(); | ||||
CReserveKey *keyChange = transaction.getPossibleKeyChange(); | CReserveKey *keyChange = transaction.getPossibleKeyChange(); | ||||
bool fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, | bool fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, | ||||
nFeeRequired, nChangePosRet, | nFeeRequired, nChangePosRet, | ||||
strFailReason, coinControl); | strFailReason, coinControl); | ||||
transaction.setTransactionFee(nFeeRequired.GetSatoshis()); | transaction.setTransactionFee(nFeeRequired); | ||||
if (fSubtractFeeFromAmount && fCreated) | if (fSubtractFeeFromAmount && fCreated) | ||||
transaction.reassignAmounts(nChangePosRet); | transaction.reassignAmounts(nChangePosRet); | ||||
if (!fCreated) { | if (!fCreated) { | ||||
if (!fSubtractFeeFromAmount && | if (!fSubtractFeeFromAmount && (total + nFeeRequired) > nBalance) { | ||||
(total + nFeeRequired.GetSatoshis()) > nBalance) { | |||||
return SendCoinsReturn(AmountWithFeeExceedsBalance); | return SendCoinsReturn(AmountWithFeeExceedsBalance); | ||||
} | } | ||||
Q_EMIT message(tr("Send Coins"), | Q_EMIT message(tr("Send Coins"), | ||||
QString::fromStdString(strFailReason), | QString::fromStdString(strFailReason), | ||||
CClientUIInterface::MSG_ERROR); | CClientUIInterface::MSG_ERROR); | ||||
return TransactionCreationFailed; | return TransactionCreationFailed; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 407 Lines • Show Last 20 Lines |