X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fqt%2Fwalletmodel.cpp;h=47b12e9d13d3fc30f1dd2033946fdefe66fbbb4b;hb=9c9ba366ebc85b0d8eef6d962a9fa84cffe0cae7;hp=a2a30ceb720c6a8c176a066c7fbcf79c1b31c92d;hpb=c0afe6a6089fe277865a89eefff01c60ad156104;p=novacoin.git diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index a2a30ce..47b12e9 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -2,6 +2,7 @@ #include "guiconstants.h" #include "optionsmodel.h" #include "addresstablemodel.h" +#include "mintingtablemodel.h" #include "transactiontablemodel.h" #include "ui_interface.h" @@ -20,7 +21,10 @@ WalletModel::WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *p cachedEncryptionStatus(Unencrypted), cachedNumBlocks(0) { + fHaveWatchOnly = wallet->HaveWatchOnly(); + addressTableModel = new AddressTableModel(wallet, this); + mintingTableModel = new MintingTableModel(wallet, this); transactionTableModel = new TransactionTableModel(wallet, this); // This timer will be fired repeatedly to update the balance @@ -36,11 +40,21 @@ WalletModel::~WalletModel() unsubscribeFromCoreSignals(); } +bool WalletModel::haveWatchOnly() const +{ + return fHaveWatchOnly; +} + qint64 WalletModel::getBalance() const { return wallet->GetBalance(); } +qint64 WalletModel::getBalanceWatchOnly() const +{ + return wallet->GetWatchOnlyBalance(); +} + qint64 WalletModel::getUnconfirmedBalance() const { return wallet->GetUnconfirmedBalance(); @@ -61,7 +75,7 @@ int WalletModel::getNumTransactions() const int numTransactions = 0; { LOCK(wallet->cs_wallet); - numTransactions = wallet->mapWallet.size(); + numTransactions = (int)(wallet->mapWallet.size()); } return numTransactions; } @@ -86,18 +100,18 @@ void WalletModel::pollBalanceChanged() void WalletModel::checkBalanceChanged() { - qint64 newBalance = getBalance(); + qint64 newBalanceTotal=getBalance(), newBalanceWatchOnly=getBalanceWatchOnly(); qint64 newStake = getStake(); qint64 newUnconfirmedBalance = getUnconfirmedBalance(); qint64 newImmatureBalance = getImmatureBalance(); - if(cachedBalance != newBalance || cachedUnconfirmedBalance != newUnconfirmedBalance || cachedImmatureBalance != newImmatureBalance) + if(cachedBalance != newBalanceTotal || cachedStake != newStake || cachedUnconfirmedBalance != newUnconfirmedBalance || cachedImmatureBalance != newImmatureBalance) { - cachedBalance = newBalance; + cachedBalance = newBalanceTotal; cachedStake = newStake; cachedUnconfirmedBalance = newUnconfirmedBalance; cachedImmatureBalance = newImmatureBalance; - emit balanceChanged(newBalance, newStake, newUnconfirmedBalance, newImmatureBalance); + emit balanceChanged(newBalanceTotal, newBalanceWatchOnly, newStake, newUnconfirmedBalance, newImmatureBalance); } } @@ -123,13 +137,19 @@ void WalletModel::updateAddressBook(const QString &address, const QString &label addressTableModel->updateEntry(address, label, isMine, status); } +void WalletModel::updateWatchOnlyFlag(bool fHaveWatchonly) +{ + fHaveWatchOnly = fHaveWatchonly; + emit notifyWatchonlyChanged(fHaveWatchonly); +} + bool WalletModel::validateAddress(const QString &address) { CBitcoinAddress addressParsed(address.toStdString()); return addressParsed.IsValid(); } -WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList &recipients) +WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList &recipients, const CCoinControl *coinControl) { qint64 total = 0; QSet setAddress; @@ -161,12 +181,20 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList getBalance()) + int64_t nBalance = 0; + std::vector vCoins; + wallet->AvailableCoins(vCoins, true, coinControl); + + BOOST_FOREACH(const COutput& out, vCoins) + if(out.fSpendable) + nBalance += out.tx->vout[out.i].nValue; + + if(total > nBalance) { return AmountExceedsBalance; } - if((total + nTransactionFee) > getBalance()) + if((total + nTransactionFee) > nBalance) { return SendCoinsReturn(AmountWithFeeExceedsBalance, nTransactionFee); } @@ -175,7 +203,7 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QListcs_wallet); // Sendmany - std::vector > vecSend; + std::vector > vecSend; foreach(const SendCoinsRecipient &rcp, recipients) { CScript scriptPubKey; @@ -185,12 +213,12 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QListCreateTransaction(vecSend, wtx, keyChange, nFeeRequired); + int64_t nFeeRequired = 0; + bool fCreated = wallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, coinControl); if(!fCreated) { - if((total + nFeeRequired) > wallet->GetBalance()) + if((total + nFeeRequired) > nBalance) // FIXME: could cause collisions in the future { return SendCoinsReturn(AmountWithFeeExceedsBalance, nFeeRequired); } @@ -239,6 +267,11 @@ AddressTableModel *WalletModel::getAddressTableModel() return addressTableModel; } +MintingTableModel *WalletModel::getMintingTableModel() +{ + return mintingTableModel; +} + TransactionTableModel *WalletModel::getTransactionTableModel() { return transactionTableModel; @@ -269,8 +302,8 @@ bool WalletModel::setWalletEncrypted(bool encrypted, const SecureString &passphr } else { - // Decrypt -- TODO; not supported yet - return false; + // Decrypt + return wallet->DecryptWallet(passphrase); } } @@ -299,6 +332,21 @@ bool WalletModel::changePassphrase(const SecureString &oldPass, const SecureStri return retval; } +void WalletModel::getStakeWeightFromValue(const int64_t& nTime, const int64_t& nValue, uint64_t& nWeight) +{ + wallet->GetStakeWeightFromValue(nTime, nValue, nWeight); +} + +bool WalletModel::dumpWallet(const QString &filename) +{ + return DumpWallet(wallet, filename.toLocal8Bit().data()); +} + +bool WalletModel::importWallet(const QString &filename) +{ + return ImportWallet(wallet, filename.toLocal8Bit().data()); +} + bool WalletModel::backupWallet(const QString &filename) { return BackupWallet(*wallet, filename.toLocal8Bit().data()); @@ -329,12 +377,19 @@ static void NotifyTransactionChanged(WalletModel *walletmodel, CWallet *wallet, Q_ARG(int, status)); } +static void NotifyWatchonlyChanged(WalletModel *walletmodel, bool fHaveWatchonly) +{ + QMetaObject::invokeMethod(walletmodel, "updateWatchOnlyFlag", Qt::QueuedConnection, + Q_ARG(bool, fHaveWatchonly)); +} + void WalletModel::subscribeToCoreSignals() { // Connect signals to wallet wallet->NotifyStatusChanged.connect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1)); wallet->NotifyAddressBookChanged.connect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5)); wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3)); + wallet->NotifyWatchonlyChanged.connect(boost::bind(NotifyWatchonlyChanged, this, _1)); } void WalletModel::unsubscribeFromCoreSignals() @@ -343,12 +398,20 @@ void WalletModel::unsubscribeFromCoreSignals() wallet->NotifyStatusChanged.disconnect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1)); wallet->NotifyAddressBookChanged.disconnect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5)); wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3)); + wallet->NotifyWatchonlyChanged.disconnect(boost::bind(NotifyWatchonlyChanged, this, _1)); } // WalletModel::UnlockContext implementation WalletModel::UnlockContext WalletModel::requestUnlock() { bool was_locked = getEncryptionStatus() == Locked; + bool mintflag = fWalletUnlockMintOnly; + + if ((!was_locked) && fWalletUnlockMintOnly) + { + setWalletLocked(true); + was_locked = getEncryptionStatus() == Locked; + } if(was_locked) { // Request UI to unlock wallet @@ -357,13 +420,14 @@ WalletModel::UnlockContext WalletModel::requestUnlock() // If wallet is still locked, unlock was failed or cancelled, mark context as invalid bool valid = getEncryptionStatus() != Locked; - return UnlockContext(this, valid, was_locked); + return UnlockContext(this, valid, was_locked, mintflag); } -WalletModel::UnlockContext::UnlockContext(WalletModel *wallet, bool valid, bool relock): +WalletModel::UnlockContext::UnlockContext(WalletModel *wallet, bool valid, bool relock, bool mintflag): wallet(wallet), valid(valid), - relock(relock) + relock(relock), + mintflag(mintflag) { } @@ -371,7 +435,14 @@ WalletModel::UnlockContext::~UnlockContext() { if(valid && relock) { + if (mintflag) + { + // Restore unlock minting flag + fWalletUnlockMintOnly = mintflag; + return; + } wallet->setWalletLocked(true); + } } @@ -381,3 +452,83 @@ 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(), true); + 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; + + // 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(), true); + if (outpoint.n < out.tx->vout.size() && wallet->IsMine(out.tx->vout[outpoint.n]) == MINE_SPENDABLE) + 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, true); + } + + std::string address; + if(!out.fSpendable || !wallet->ExtractAddress(cout.tx->vout[cout.i].scriptPubKey, address)) + continue; + + mapCoins[address.c_str()].push_back(out); + } +} + +bool WalletModel::isLockedCoin(uint256 hash, unsigned int n) const +{ + return false; +} + +void WalletModel::lockCoin(COutPoint& output) +{ + return; +} + +void WalletModel::unlockCoin(COutPoint& output) +{ + return; +} + +void WalletModel::listLockedCoins(std::vector& vOutpts) +{ + return; +} + +void WalletModel::clearOrphans() +{ + wallet->ClearOrphans(); +} + +CWallet* WalletModel::getWallet() +{ + return wallet; +} \ No newline at end of file