diff options
Diffstat (limited to 'src/qt')
-rw-r--r-- | src/qt/bitcoin.cpp | 9 | ||||
-rw-r--r-- | src/qt/bitcoingui.cpp | 6 | ||||
-rw-r--r-- | src/qt/bitcoingui.h | 2 | ||||
-rw-r--r-- | src/qt/paymentserver.cpp | 36 | ||||
-rw-r--r-- | src/qt/paymentserver.h | 6 | ||||
-rw-r--r-- | src/qt/rpcconsole.cpp | 42 | ||||
-rw-r--r-- | src/qt/rpcconsole.h | 2 | ||||
-rw-r--r-- | src/qt/sendcoinsdialog.cpp | 3 | ||||
-rw-r--r-- | src/qt/splashscreen.cpp | 2 | ||||
-rw-r--r-- | src/qt/test/paymentservertests.cpp | 3 | ||||
-rw-r--r-- | src/qt/test/test_main.cpp | 4 | ||||
-rw-r--r-- | src/qt/transactiondesc.cpp | 4 | ||||
-rw-r--r-- | src/qt/transactionrecord.cpp | 6 | ||||
-rw-r--r-- | src/qt/walletmodel.cpp | 5 | ||||
-rw-r--r-- | src/qt/walletmodel.h | 1 | ||||
-rw-r--r-- | src/qt/walletview.cpp | 21 | ||||
-rw-r--r-- | src/qt/walletview.h | 3 |
17 files changed, 108 insertions, 47 deletions
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 1da2d3e344..ea7f86d18e 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -266,13 +266,6 @@ void BitcoinCore::initialize() { qDebug() << __func__ << ": Running AppInit2 in thread"; int rv = AppInit2(threadGroup, scheduler); - if(rv) - { - /* Start a dummy RPC thread if no RPC thread is active yet - * to handle timeouts. - */ - StartDummyRPCThread(); - } Q_EMIT initializeResult(rv); } catch (const std::exception& e) { handleRunawayException(&e); @@ -286,7 +279,7 @@ void BitcoinCore::shutdown() try { qDebug() << __func__ << ": Running Shutdown in thread"; - threadGroup.interrupt_all(); + Interrupt(threadGroup); threadGroup.join_all(); Shutdown(); qDebug() << __func__ << ": Shutdown finished"; diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 1d3f7762ab..db9e558764 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -97,6 +97,7 @@ BitcoinGUI::BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *n trayIconMenu(0), notificator(0), rpcConsole(0), + helpMessageDialog(0), prevBlocks(0), spinnerFrame(0), platformStyle(platformStyle) @@ -132,6 +133,7 @@ BitcoinGUI::BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *n #endif rpcConsole = new RPCConsole(platformStyle, 0); + helpMessageDialog = new HelpMessageDialog(this, false); #ifdef ENABLE_WALLET if(enableWallet) { @@ -590,9 +592,7 @@ void BitcoinGUI::aboutClicked() void BitcoinGUI::showHelpMessageClicked() { - HelpMessageDialog *help = new HelpMessageDialog(this, false); - help->setAttribute(Qt::WA_DeleteOnClose); - help->show(); + helpMessageDialog->show(); } #ifdef ENABLE_WALLET diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index dd0d4bb0e2..f1b7a502ba 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -28,6 +28,7 @@ class SendCoinsRecipient; class UnitDisplayStatusBarControl; class WalletFrame; class WalletModel; +class HelpMessageDialog; class CWallet; @@ -113,6 +114,7 @@ private: QMenu *trayIconMenu; Notificator *notificator; RPCConsole *rpcConsole; + HelpMessageDialog *helpMessageDialog; /** Keep track of previous number of blocks, to detect progress */ int prevBlocks; diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 0827d99125..31a6d65a8d 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -509,12 +509,7 @@ bool PaymentServer::readPaymentRequestFromFile(const QString& filename, PaymentR } // BIP70 DoS protection - if (f.size() > BIP70_MAX_PAYMENTREQUEST_SIZE) { - qWarning() << QString("PaymentServer::%1: Payment request %2 is too large (%3 bytes, allowed %4 bytes).") - .arg(__func__) - .arg(filename) - .arg(f.size()) - .arg(BIP70_MAX_PAYMENTREQUEST_SIZE); + if (!verifySize(f.size())) { return false; } @@ -685,14 +680,13 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply) reply->deleteLater(); // BIP70 DoS protection - if (reply->size() > BIP70_MAX_PAYMENTREQUEST_SIZE) { - QString msg = tr("Payment request %1 is too large (%2 bytes, allowed %3 bytes).") - .arg(reply->request().url().toString()) - .arg(reply->size()) - .arg(BIP70_MAX_PAYMENTREQUEST_SIZE); - - qWarning() << QString("PaymentServer::%1:").arg(__func__) << msg; - Q_EMIT message(tr("Payment request DoS protection"), msg, CClientUIInterface::MSG_ERROR); + if (!verifySize(reply->size())) { + Q_EMIT message(tr("Payment request rejected"), + tr("Payment request %1 is too large (%2 bytes, allowed %3 bytes).") + .arg(reply->request().url().toString()) + .arg(reply->size()) + .arg(BIP70_MAX_PAYMENTREQUEST_SIZE), + CClientUIInterface::MSG_ERROR); return; } @@ -762,7 +756,7 @@ void PaymentServer::setOptionsModel(OptionsModel *optionsModel) void PaymentServer::handlePaymentACK(const QString& paymentACKMsg) { - // currently we don't futher process or store the paymentACK message + // currently we don't further process or store the paymentACK message Q_EMIT message(tr("Payment acknowledged"), paymentACKMsg, CClientUIInterface::ICON_INFORMATION | CClientUIInterface::MODAL); } @@ -790,6 +784,18 @@ bool PaymentServer::verifyExpired(const payments::PaymentDetails& requestDetails return fVerified; } +bool PaymentServer::verifySize(qint64 requestSize) +{ + bool fVerified = (requestSize <= BIP70_MAX_PAYMENTREQUEST_SIZE); + if (!fVerified) { + qWarning() << QString("PaymentServer::%1: Payment request too large (%2 bytes, allowed %3 bytes).") + .arg(__func__) + .arg(requestSize) + .arg(BIP70_MAX_PAYMENTREQUEST_SIZE); + } + return fVerified; +} + bool PaymentServer::verifyAmount(const CAmount& requestAmount) { bool fVerified = MoneyRange(requestAmount); diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h index 5df0a14cf7..fa120a435c 100644 --- a/src/qt/paymentserver.h +++ b/src/qt/paymentserver.h @@ -88,13 +88,12 @@ public: // OptionsModel is used for getting proxy settings and display unit void setOptionsModel(OptionsModel *optionsModel); - // This is now public, because we use it in paymentservertests.cpp - static bool readPaymentRequestFromFile(const QString& filename, PaymentRequestPlus& request); - // Verify that the payment request network matches the client network static bool verifyNetwork(const payments::PaymentDetails& requestDetails); // Verify if the payment request is expired static bool verifyExpired(const payments::PaymentDetails& requestDetails); + // Verify the payment request size is valid as per BIP70 + static bool verifySize(qint64 requestSize); // Verify the payment request amount is valid static bool verifyAmount(const CAmount& requestAmount); @@ -131,6 +130,7 @@ protected: bool eventFilter(QObject *object, QEvent *event); private: + static bool readPaymentRequestFromFile(const QString& filename, PaymentRequestPlus& request); bool processPaymentRequest(const PaymentRequestPlus& request, SendCoinsRecipient& recipient); void fetchRequest(const QUrl& url); diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 14339e1ab5..ec18ea8f71 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -27,6 +27,7 @@ #include <QScrollBar> #include <QThread> #include <QTime> +#include <QTimer> #if QT_VERSION < 0x050000 #include <QUrl> @@ -65,6 +66,40 @@ Q_SIGNALS: void reply(int category, const QString &command); }; +/** Class for handling RPC timers + * (used for e.g. re-locking the wallet after a timeout) + */ +class QtRPCTimerBase: public QObject, public RPCTimerBase +{ + Q_OBJECT +public: + QtRPCTimerBase(boost::function<void(void)>& func, int64_t millis): + func(func) + { + timer.setSingleShot(true); + connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); + timer.start(millis); + } + ~QtRPCTimerBase() {} +private Q_SLOTS: + void timeout() { func(); } +private: + QTimer timer; + boost::function<void(void)> func; +}; + +class QtRPCTimerInterface: public RPCTimerInterface +{ +public: + ~QtRPCTimerInterface() {} + const char *Name() { return "Qt"; } + RPCTimerBase* NewTimer(boost::function<void(void)>& func, int64_t millis) + { + return new QtRPCTimerBase(func, millis); + } +}; + + #include "rpcconsole.moc" /** @@ -231,6 +266,9 @@ RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) : ui->label_berkeleyDBVersion->hide(); ui->berkeleyDBVersion->hide(); #endif + // Register RPC timer interface + rpcTimerInterface = new QtRPCTimerInterface(); + RPCRegisterTimerInterface(rpcTimerInterface); startExecutor(); setTrafficGraphRange(INITIAL_TRAFFIC_GRAPH_MINS); @@ -245,6 +283,8 @@ RPCConsole::~RPCConsole() { GUIUtil::saveWindowGeometry("nRPCConsoleWindow", this); Q_EMIT stopExecutor(); + RPCUnregisterTimerInterface(rpcTimerInterface); + delete rpcTimerInterface; delete ui; } @@ -569,7 +609,7 @@ void RPCConsole::peerLayoutChanged() if (detailNodeRow < 0) { - // detail node dissapeared from table (node disconnected) + // detail node disappeared from table (node disconnected) fUnselect = true; } else diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index b94efee84a..1409fca525 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -14,6 +14,7 @@ class ClientModel; class PlatformStyle; +class RPCTimerInterface; namespace Ui { class RPCConsole; @@ -108,6 +109,7 @@ private: NodeId cachedNodeid; QMenu *contextMenu; const PlatformStyle *platformStyle; + RPCTimerInterface *rpcTimerInterface; }; #endif // BITCOIN_QT_RPCCONSOLE_H diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 449a7bc5e8..60a3fc128e 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -754,10 +754,9 @@ void SendCoinsDialog::coinControlChangeEdited(const QString& text) } else // Valid address { - CPubKey pubkey; CKeyID keyid; addr.GetKeyID(keyid); - if (!model->getPubKey(keyid, pubkey)) // Unknown change address + if (!model->havePrivKey(keyid)) // Unknown change address { ui->labelCoinControlChangeLabel->setText(tr("Warning: Unknown change address")); } diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index 8430e017c1..c15b64c327 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -57,7 +57,7 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle) QPainter pixPaint(&pixmap); pixPaint.setPen(QColor(100,100,100)); - // draw a slighly radial gradient + // draw a slightly radial gradient QRadialGradient gradient(QPoint(0,0), splashSize.width()/devicePixelRatio); gradient.setColorAt(0, Qt::white); gradient.setColorAt(1, QColor(247,247,247)); diff --git a/src/qt/test/paymentservertests.cpp b/src/qt/test/paymentservertests.cpp index b28934cd31..fa5696325d 100644 --- a/src/qt/test/paymentservertests.cpp +++ b/src/qt/test/paymentservertests.cpp @@ -185,7 +185,8 @@ void PaymentServerTests::paymentServerTests() tempFile.open(); tempFile.write((const char*)randData, sizeof(randData)); tempFile.close(); - QCOMPARE(PaymentServer::readPaymentRequestFromFile(tempFile.fileName(), r.paymentRequest), false); + // compares 50001 <= BIP70_MAX_PAYMENTREQUEST_SIZE == false + QCOMPARE(PaymentServer::verifySize(tempFile.size()), false); // Payment request with amount overflow (amount is set to 21000001 BTC): data = DecodeBase64(paymentrequest5_cert2_BASE64); diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp index bb768f1325..f91de2008c 100644 --- a/src/qt/test/test_main.cpp +++ b/src/qt/test/test_main.cpp @@ -17,6 +17,8 @@ #include <QObject> #include <QTest> +#include <openssl/ssl.h> + #if defined(QT_STATICPLUGIN) && QT_VERSION < 0x050000 #include <QtPlugin> Q_IMPORT_PLUGIN(qcncodecs) @@ -36,6 +38,8 @@ int main(int argc, char *argv[]) QCoreApplication app(argc, argv); app.setApplicationName("Bitcoin-Qt-test"); + SSL_library_init(); + URITests test1; if (QTest::qExec(&test1) != 0) fInvalid = true; diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index af78a51d0f..801c6c62d2 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -165,7 +165,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco if (fAllFromMe) { - if(fAllFromMe == ISMINE_WATCH_ONLY) + if(fAllFromMe & ISMINE_WATCH_ONLY) strHTML += "<b>" + tr("From") + ":</b> " + tr("watch-only") + "<br>"; // @@ -190,7 +190,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(address).ToString()); if(toSelf == ISMINE_SPENDABLE) strHTML += " (own address)"; - else if(toSelf == ISMINE_WATCH_ONLY) + else if(toSelf & ISMINE_WATCH_ONLY) strHTML += " (watch-only)"; strHTML += "<br>"; } diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 15d13e9fc9..d8623daf5d 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -56,7 +56,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet * CTxDestination address; sub.idx = parts.size(); // sequence number sub.credit = txout.nValue; - sub.involvesWatchAddress = mine == ISMINE_WATCH_ONLY; + sub.involvesWatchAddress = mine & ISMINE_WATCH_ONLY; if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address)) { // Received by Bitcoin Address @@ -86,7 +86,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet * BOOST_FOREACH(const CTxIn& txin, wtx.vin) { isminetype mine = wallet->IsMine(txin); - if(mine == ISMINE_WATCH_ONLY) involvesWatchAddress = true; + if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true; if(fAllFromMe > mine) fAllFromMe = mine; } @@ -94,7 +94,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet * BOOST_FOREACH(const CTxOut& txout, wtx.vout) { isminetype mine = wallet->IsMine(txout); - if(mine == ISMINE_WATCH_ONLY) involvesWatchAddress = true; + if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true; if(fAllToMe > mine) fAllToMe = mine; } diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index f580853732..5c21db8bdf 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -556,6 +556,11 @@ bool WalletModel::getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const return wallet->GetPubKey(address, vchPubKeyOut); } +bool WalletModel::havePrivKey(const CKeyID &address) const +{ + return wallet->HaveKey(address); +} + // returns a list of COutputs from COutPoints void WalletModel::getOutputs(const std::vector<COutPoint>& vOutpoints, std::vector<COutput>& vOutputs) { diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index c29682e4f6..a5e877d81f 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -187,6 +187,7 @@ public: UnlockContext requestUnlock(); bool getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const; + bool havePrivKey(const CKeyID &address) const; void getOutputs(const std::vector<COutPoint>& vOutpoints, std::vector<COutput>& vOutputs); bool isSpent(const COutPoint& outpoint) const; void listCoins(std::map<QString, std::vector<COutput> >& mapCoins) const; diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index fa96f62e03..77efdb5cdd 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -56,6 +56,9 @@ WalletView::WalletView(const PlatformStyle *platformStyle, QWidget *parent): receiveCoinsPage = new ReceiveCoinsDialog(platformStyle); sendCoinsPage = new SendCoinsDialog(platformStyle); + usedSendingAddressesPage = new AddressBookPage(platformStyle, AddressBookPage::ForEditing, AddressBookPage::SendingTab, this); + usedReceivingAddressesPage = new AddressBookPage(platformStyle, AddressBookPage::ForEditing, AddressBookPage::ReceivingTab, this); + addWidget(overviewPage); addWidget(transactionsPage); addWidget(receiveCoinsPage); @@ -115,6 +118,8 @@ void WalletView::setWalletModel(WalletModel *walletModel) overviewPage->setWalletModel(walletModel); receiveCoinsPage->setModel(walletModel); sendCoinsPage->setModel(walletModel); + usedReceivingAddressesPage->setModel(walletModel->getAddressTableModel()); + usedSendingAddressesPage->setModel(walletModel->getAddressTableModel()); if (walletModel) { @@ -273,20 +278,20 @@ void WalletView::usedSendingAddresses() { if(!walletModel) return; - AddressBookPage *dlg = new AddressBookPage(platformStyle, AddressBookPage::ForEditing, AddressBookPage::SendingTab, this); - dlg->setAttribute(Qt::WA_DeleteOnClose); - dlg->setModel(walletModel->getAddressTableModel()); - dlg->show(); + + usedSendingAddressesPage->show(); + usedSendingAddressesPage->raise(); + usedSendingAddressesPage->activateWindow(); } void WalletView::usedReceivingAddresses() { if(!walletModel) return; - AddressBookPage *dlg = new AddressBookPage(platformStyle, AddressBookPage::ForEditing, AddressBookPage::ReceivingTab, this); - dlg->setAttribute(Qt::WA_DeleteOnClose); - dlg->setModel(walletModel->getAddressTableModel()); - dlg->show(); + + usedReceivingAddressesPage->show(); + usedReceivingAddressesPage->raise(); + usedReceivingAddressesPage->activateWindow(); } void WalletView::showProgress(const QString &title, int nProgress) diff --git a/src/qt/walletview.h b/src/qt/walletview.h index f97cf1ee80..2a6a6a2df2 100644 --- a/src/qt/walletview.h +++ b/src/qt/walletview.h @@ -18,6 +18,7 @@ class SendCoinsDialog; class SendCoinsRecipient; class TransactionView; class WalletModel; +class AddressBookPage; QT_BEGIN_NAMESPACE class QModelIndex; @@ -61,6 +62,8 @@ private: QWidget *transactionsPage; ReceiveCoinsDialog *receiveCoinsPage; SendCoinsDialog *sendCoinsPage; + AddressBookPage *usedSendingAddressesPage; + AddressBookPage *usedReceivingAddressesPage; TransactionView *transactionView; |