From 7993454a927f3c4cf5ac935c613afeeb68f35f0a Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 5 Apr 2012 18:58:20 -0400 Subject: [PATCH 01/20] Document strlcpy.h in assets-attribution.txt since it isn't MIT-licensed --- doc/assets-attribution.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/assets-attribution.txt b/doc/assets-attribution.txt index 8d23f7e59cd..ffaec44f18d 100644 --- a/doc/assets-attribution.txt +++ b/doc/assets-attribution.txt @@ -1,3 +1,7 @@ +Code: src/strlcpy.h +Author: Todd C. Miller +License: ISC + Icon: src/qt/res/icons/clock*.png, src/qt/res/icons/tx*.png, src/qt/res/src/*.svg Designer: Wladimir van der Laan From ce333560949c8b89fac4dfb5112d3a808a8d4ff8 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sun, 25 Mar 2012 17:25:10 -0400 Subject: [PATCH 02/20] Bugfix: Replace "URL" with "URI" where we aren't actually working with URLs --- src/qt/bitcoingui.cpp | 8 ++++---- src/qt/guiutil.cpp | 20 ++++++++++---------- src/qt/guiutil.h | 8 ++++---- src/qt/sendcoinsdialog.cpp | 8 ++++---- src/qt/sendcoinsdialog.h | 4 ++-- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index be608381713..0111ebbc9d7 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -659,7 +659,7 @@ void BitcoinGUI::gotoSendCoinsPage() void BitcoinGUI::dragEnterEvent(QDragEnterEvent *event) { - // Accept only URLs + // Accept only URIs if(event->mimeData()->hasUrls()) event->acceptProposedAction(); } @@ -669,10 +669,10 @@ void BitcoinGUI::dropEvent(QDropEvent *event) if(event->mimeData()->hasUrls()) { gotoSendCoinsPage(); - QList urls = event->mimeData()->urls(); - foreach(const QUrl &url, urls) + QList uris = event->mimeData()->urls(); + foreach(const QUrl &uri, uris) { - sendCoinsPage->handleURL(&url); + sendCoinsPage->handleURI(&uri); } } diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index d1490c8f705..f5e6e0a545f 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -47,16 +47,16 @@ void GUIUtil::setupAmountWidget(QLineEdit *widget, QWidget *parent) widget->setAlignment(Qt::AlignRight|Qt::AlignVCenter); } -bool GUIUtil::parseBitcoinURL(const QUrl *url, SendCoinsRecipient *out) +bool GUIUtil::parseBitcoinURI(const QUrl *uri, SendCoinsRecipient *out) { - if(url->scheme() != QString("bitcoin")) + if(uri->scheme() != QString("bitcoin")) return false; SendCoinsRecipient rv; - rv.address = url->path(); - rv.label = url->queryItemValue("label"); + rv.address = uri->path(); + rv.label = uri->queryItemValue("label"); - QString amount = url->queryItemValue("amount"); + QString amount = uri->queryItemValue("amount"); if(amount.isEmpty()) { rv.amount = 0; @@ -75,18 +75,18 @@ bool GUIUtil::parseBitcoinURL(const QUrl *url, SendCoinsRecipient *out) return true; } -bool GUIUtil::parseBitcoinURL(QString url, SendCoinsRecipient *out) +bool GUIUtil::parseBitcoinURI(QString uri, SendCoinsRecipient *out) { // Convert bitcoin:// to bitcoin: // // Cannot handle this later, because bitcoin:// will cause Qt to see the part after // as host, // which will lowercase it (and thus invalidate the address). - if(url.startsWith("bitcoin://")) + if(uri.startsWith("bitcoin://")) { - url.replace(0, 10, "bitcoin:"); + uri.replace(0, 10, "bitcoin:"); } - QUrl urlInstance(url); - return parseBitcoinURL(&urlInstance, out); + QUrl uriInstance(uri); + return parseBitcoinURI(&uriInstance, out); } QString GUIUtil::getSaveFileName(QWidget *parent, const QString &caption, diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index d7523aa15c9..8e75ee23ad2 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -26,10 +26,10 @@ public: static void setupAddressWidget(QLineEdit *widget, QWidget *parent); static void setupAmountWidget(QLineEdit *widget, QWidget *parent); - // Parse "bitcoin:" URL into recipient object, return true on succesful parsing - // See Bitcoin URL definition discussion here: https://bitcointalk.org/index.php?topic=33490.0 - static bool parseBitcoinURL(const QUrl *url, SendCoinsRecipient *out); - static bool parseBitcoinURL(QString url, SendCoinsRecipient *out); + // Parse "bitcoin:" URI into recipient object, return true on succesful parsing + // See Bitcoin URI definition discussion here: https://bitcointalk.org/index.php?topic=33490.0 + static bool parseBitcoinURI(const QUrl *, SendCoinsRecipient *out); + static bool parseBitcoinURI(QString uri, SendCoinsRecipient *out); /** Get save file name, mimics QFileDialog::getSaveFileName, except that it appends a default suffix when no suffix is provided by the user. diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index e465b4141a4..657761515b0 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -255,20 +255,20 @@ void SendCoinsDialog::pasteEntry(const SendCoinsRecipient &rv) } -void SendCoinsDialog::handleURL(const QUrl *url) +void SendCoinsDialog::handleURI(const QUrl *uri) { SendCoinsRecipient rv; - if(!GUIUtil::parseBitcoinURL(url, &rv)) + if(!GUIUtil::parseBitcoinURI(uri, &rv)) { return; } pasteEntry(rv); } -void SendCoinsDialog::handleURL(const QString &url) +void SendCoinsDialog::handleURI(const QString &uri) { SendCoinsRecipient rv; - if(!GUIUtil::parseBitcoinURL(url, &rv)) + if(!GUIUtil::parseBitcoinURI(uri, &rv)) { return; } diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h index fdff05783eb..7da0a7fa072 100644 --- a/src/qt/sendcoinsdialog.h +++ b/src/qt/sendcoinsdialog.h @@ -29,8 +29,8 @@ public: QWidget *setupTabChain(QWidget *prev); void pasteEntry(const SendCoinsRecipient &rv); - void handleURL(const QUrl *url); - void handleURL(const QString &url); + void handleURI(const QUrl *uri); + void handleURI(const QString &uri); public slots: void clear(); From bf1f995c4c968f4325ac05474fcfd87924d62e36 Mon Sep 17 00:00:00 2001 From: p2k Date: Mon, 12 Mar 2012 14:20:55 +0100 Subject: [PATCH 03/20] Proper support for Growl 1.3 notifications --- src/qt/notificator.cpp | 15 ++++++++++----- src/qt/notificator.h | 3 ++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/qt/notificator.cpp b/src/qt/notificator.cpp index a2314caa471..e668079536e 100644 --- a/src/qt/notificator.cpp +++ b/src/qt/notificator.cpp @@ -52,10 +52,13 @@ Notificator::Notificator(const QString &programName, QSystemTrayIcon *trayicon, OSStatus status = LSGetApplicationForInfo(kLSUnknownType, kLSUnknownCreator, CFSTR("growlTicket"), kLSRolesAll, 0, &cfurl); if (status != kLSApplicationNotFoundErr) { CFBundleRef bundle = CFBundleCreate(0, cfurl); - CFRelease(cfurl); if (CFStringCompare(CFBundleGetIdentifier(bundle), CFSTR("com.Growl.GrowlHelperApp"), kCFCompareCaseInsensitive | kCFCompareBackwards) == kCFCompareEqualTo) { - mode = Growl; + if (CFStringHasSuffix(CFURLGetString(cfurl), CFSTR("/Growl.app/"))) + mode = Growl13; + else + mode = Growl12; } + CFRelease(cfurl); CFRelease(bundle); } #endif @@ -226,7 +229,7 @@ void Notificator::notifySystray(Class cls, const QString &title, const QString & void Notificator::notifyGrowl(Class cls, const QString &title, const QString &text, const QIcon &icon) { const QString script( - "tell application \"GrowlHelperApp\"\n" + "tell application \"%5\"\n" " set the allNotificationsList to {\"Notification\"}\n" // -- Make a list of all the notification types (all) " set the enabledNotificationsList to {\"Notification\"}\n" // -- Make a list of the notifications (enabled) " register as application \"%1\" all notifications allNotificationsList default notifications enabledNotificationsList\n" // -- Register our script with Growl @@ -265,7 +268,8 @@ void Notificator::notifyGrowl(Class cls, const QString &title, const QString &te QString quotedTitle(title), quotedText(text); quotedTitle.replace("\\", "\\\\").replace("\"", "\\"); quotedText.replace("\\", "\\\\").replace("\"", "\\"); - qt_mac_execute_apple_script(script.arg(notificationApp, quotedTitle, quotedText, notificationIcon), 0); + QString growlApp(this->mode == Notificator::Growl13 ? "Growl" : "GrowlHelperApp"); + qt_mac_execute_apple_script(script.arg(notificationApp, quotedTitle, quotedText, notificationIcon, growlApp), 0); } #endif @@ -282,7 +286,8 @@ void Notificator::notify(Class cls, const QString &title, const QString &text, c notifySystray(cls, title, text, icon, millisTimeout); break; #ifdef Q_WS_MAC - case Growl: + case Growl12: + case Growl13: notifyGrowl(cls, title, text, icon); break; #endif diff --git a/src/qt/notificator.h b/src/qt/notificator.h index ed69ae5c611..dba39f3971c 100644 --- a/src/qt/notificator.h +++ b/src/qt/notificator.h @@ -48,7 +48,8 @@ private: None, Freedesktop, // Use DBus org.freedesktop.Notifications QSystemTray, // Use QSystemTray::showMessage - Growl // Use the Growl notification system (Mac only) + Growl12, // Use the Growl 1.2 notification system (Mac only) + Growl13 // Use the Growl 1.3 notification system (Mac only) }; QString programName; Mode mode; From 527b512cf754bc7846852f3a4a61d8b364c5abc3 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Fri, 6 Apr 2012 17:44:26 -0400 Subject: [PATCH 04/20] Bugfix: Windows lacks sleep(), so need to use Sleep() from util.h --- src/qt/bitcoin.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 311fab3c9b9..1133f122e73 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -8,6 +8,7 @@ #include "headers.h" #include "init.h" +#include "util.h" #include #include @@ -45,7 +46,7 @@ int ThreadSafeMessageBox(const std::string& message, const std::string& caption, if (modal) while (!guiref) - sleep(1); + Sleep(1000); // Message from network thread if(guiref) From 1f56046fd529c0ef9e35d26d68995c497751c54f Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 5 Apr 2012 20:36:27 +0200 Subject: [PATCH 05/20] Show error message instead of exception crash when unable to bind RPC port Fixes issue #875 --- src/bitcoinrpc.cpp | 22 ++++++++++++++++++++++ src/qt/bitcoingui.cpp | 4 ++++ 2 files changed, 26 insertions(+) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index a4a1fd4d6b3..ac20ae86109 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -2161,6 +2161,10 @@ void ThreadRPCServer(void* parg) printf("ThreadRPCServer exiting\n"); } +#ifdef QT_GUI +extern bool HACK_SHUTDOWN; +#endif + void ThreadRPCServer2(void* parg) { printf("ThreadRPCServer started\n"); @@ -2196,9 +2200,27 @@ void ThreadRPCServer2(void* parg) asio::io_service io_service; ip::tcp::endpoint endpoint(bindAddress, GetArg("-rpcport", 8332)); +#ifndef QT_GUI ip::tcp::acceptor acceptor(io_service, endpoint); acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); +#else + ip::tcp::acceptor acceptor(io_service); + try + { + acceptor.open(endpoint.protocol()); + acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); + acceptor.bind(endpoint); + acceptor.listen(socket_base::max_connections); + } + catch(system::system_error &e) + { + HACK_SHUTDOWN = true; + ThreadSafeMessageBox(strprintf(_("An error occured while setting up the RPC port %i for listening: %s"), endpoint.port(), e.what()), + _("Error"), wxOK | wxMODAL); + return; + } +#endif #ifdef USE_SSL ssl::context context(io_service, ssl::context::sslv23); diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 0111ebbc9d7..3433c6a1837 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -516,12 +516,16 @@ void BitcoinGUI::refreshStatusBar() setNumBlocks(clientModel->getNumBlocks()); } +bool HACK_SHUTDOWN = false; + void BitcoinGUI::error(const QString &title, const QString &message, bool modal) { // Report errors from network/worker thread if (modal) { QMessageBox::critical(this, title, message, QMessageBox::Ok, QMessageBox::Ok); + if (HACK_SHUTDOWN) + QMetaObject::invokeMethod(QCoreApplication::instance(), "quit", Qt::QueuedConnection); } else { notificator->notify(Notificator::Critical, title, message); } From e88b6b341d75536f2743ce735c338c9fe93ba272 Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Wed, 4 Apr 2012 20:56:13 -0400 Subject: [PATCH 06/20] Bug fix listtransactions from/count handling. --- src/rpc.cpp | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/src/rpc.cpp b/src/rpc.cpp index aade32ac1d8..b62da8ecdf0 100644 --- a/src/rpc.cpp +++ b/src/rpc.cpp @@ -1099,14 +1099,21 @@ Value listtransactions(const Array& params, bool fHelp) if (params.size() > 2) nFrom = params[2].get_int(); + if (nCount < 0) + throw JSONRPCError(-8, "Negative count"); + if (nFrom < 0) + throw JSONRPCError(-8, "Negative from"); + Array ret; CWalletDB walletdb(pwalletMain->strWalletFile); - // Firs: get all CWalletTx and CAccountingEntry into a sorted-by-time multimap: + // First: get all CWalletTx and CAccountingEntry into a sorted-by-time multimap. typedef pair TxPair; typedef multimap TxItems; TxItems txByTime; + // Note: maintaining indices in the database of (account,time) --> txid and (account, time) --> acentry + // would make this much faster for applications that do this a lot. for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { CWalletTx* wtx = &((*it).second); @@ -1119,10 +1126,8 @@ Value listtransactions(const Array& params, bool fHelp) txByTime.insert(make_pair(entry.nTime, TxPair((CWalletTx*)0, &entry))); } - // Now: iterate backwards until we have nCount items to return: - TxItems::reverse_iterator it = txByTime.rbegin(); - if (txByTime.size() > nFrom) std::advance(it, nFrom); - for (; it != txByTime.rend(); ++it) + // iterate backwards until we have nCount items to return: + for (TxItems::reverse_iterator it = txByTime.rbegin(); it != txByTime.rend(); ++it) { CWalletTx *const pwtx = (*it).second.first; if (pwtx != 0) @@ -1131,18 +1136,21 @@ Value listtransactions(const Array& params, bool fHelp) if (pacentry != 0) AcentryToJSON(*pacentry, strAccount, ret); - if (ret.size() >= nCount) break; + if (ret.size() >= (nCount+nFrom)) break; } - // ret is now newest to oldest + // ret is newest to oldest - // Make sure we return only last nCount items (sends-to-self might give us an extra): - if (ret.size() > nCount) - { - Array::iterator last = ret.begin(); - std::advance(last, nCount); - ret.erase(last, ret.end()); - } - std::reverse(ret.begin(), ret.end()); // oldest to newest + if (nFrom > ret.size()) nFrom = ret.size(); + if (nFrom+nCount > ret.size()) nCount = ret.size()-nFrom; + Array::iterator first = ret.begin(); + std::advance(first, nFrom); + Array::iterator last = ret.begin(); + std::advance(last, nFrom+nCount); + + if (last != ret.end()) ret.erase(last, ret.end()); + if (first != ret.begin()) ret.erase(ret.begin(), first); + + std::reverse(ret.begin(), ret.end()); // Return oldest to newest return ret; } From 1f917975359cc086926653075a43d64699a64677 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 13 Apr 2012 09:16:46 +0200 Subject: [PATCH 07/20] Add missing tooltip and key shortcut in settings dialog (#1088 without line break part) --- src/qt/optionsdialog.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 75fd4ccf186..0025337ab82 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -278,7 +278,8 @@ DisplayOptionsPage::DisplayOptionsPage(QWidget *parent): layout->addLayout(unit_hbox); - display_addresses = new QCheckBox(tr("Display addresses in transaction list"), this); + display_addresses = new QCheckBox(tr("&Display addresses in transaction list"), this); + display_addresses->setToolTip(tr("Whether to show Bitcoin addresses in the transaction list")); layout->addWidget(display_addresses); layout->addStretch(); From a558054709124a7e8208ce164175f7235166bedf Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sat, 14 Apr 2012 08:21:22 +0200 Subject: [PATCH 08/20] Do not show green tick unless all known blocks are downloaded (fixes #921) --- src/qt/bitcoingui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 3433c6a1837..08ccb75b81d 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -480,7 +480,7 @@ void BitcoinGUI::setNumBlocks(int count) } // Set icon state: spinning if catching up, tick otherwise - if(secs < 90*60) + if(secs < 90*60 && count >= nTotalBlocks) { tooltip = tr("Up to date") + QString(".\n") + tooltip; labelBlocksIcon->setPixmap(QIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); From f2862f1a499265ec4209dfdc42edf57946e26803 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sat, 14 Apr 2012 18:32:30 +0200 Subject: [PATCH 09/20] Rename make_windows_icon.py to .sh as it is a shell script (fixes #1099) --- scripts/qt/{make_windows_icon.py => make_windows_icon.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename scripts/qt/{make_windows_icon.py => make_windows_icon.sh} (100%) diff --git a/scripts/qt/make_windows_icon.py b/scripts/qt/make_windows_icon.sh similarity index 100% rename from scripts/qt/make_windows_icon.py rename to scripts/qt/make_windows_icon.sh From 02a38ac22bafcd35334d31e57f41289ae1498b7a Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sat, 14 Apr 2012 15:38:26 -0400 Subject: [PATCH 10/20] Add symlink to scripts/qt/make_windows_icon.sh from old file name, just in case --- scripts/qt/make_windows_icon.py | 1 + 1 file changed, 1 insertion(+) create mode 120000 scripts/qt/make_windows_icon.py diff --git a/scripts/qt/make_windows_icon.py b/scripts/qt/make_windows_icon.py new file mode 120000 index 00000000000..f51c32a2158 --- /dev/null +++ b/scripts/qt/make_windows_icon.py @@ -0,0 +1 @@ +make_windows_icon.sh \ No newline at end of file From e962c7f53253ff08f095b52c4eed97fe36cf3520 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sun, 15 Apr 2012 13:23:34 -0400 Subject: [PATCH 11/20] Bugfix: nTotalBlocks wasn't in 0.5.0, so need to replace it with equivalent function call in backport --- src/qt/bitcoingui.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 08ccb75b81d..778acd1e00e 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -4,6 +4,9 @@ * W.J. van der Laan 2011 * The Bitcoin Developers 2011 */ + +#include "checkpoints.h" + #include "bitcoingui.h" #include "transactiontablemodel.h" #include "addressbookpage.h" @@ -480,7 +483,7 @@ void BitcoinGUI::setNumBlocks(int count) } // Set icon state: spinning if catching up, tick otherwise - if(secs < 90*60 && count >= nTotalBlocks) + if(secs < 90*60 && count >= Checkpoints::GetTotalBlocksEstimate()) { tooltip = tr("Up to date") + QString(".\n") + tooltip; labelBlocksIcon->setPixmap(QIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); From cb1035a00882405fac47eb92e7086c7231062e3d Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sat, 14 Apr 2012 09:41:05 +0200 Subject: [PATCH 12/20] Show a message box when runaway exception happens This is more clear to users than when the program simply disappears (usually during initialization). It still logs the message to the console and debug log as well. --- src/qt/bitcoin.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 1133f122e73..74ace600e0f 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -120,6 +120,15 @@ std::string _(const char* psz) return QCoreApplication::translate("bitcoin-core", psz).toStdString(); } +/* Handle runaway exceptions. Shows a message box with the problem and quits the program. + */ +static void handleRunawayException(std::exception *e) +{ + PrintExceptionContinue(e, "Runaway exception"); + QMessageBox::critical(0, "Runaway exception", BitcoinGUI::tr("A fatal error occured. Bitcoin can no longer continue safely and will quit.") + QString("\n\n") + QString::fromStdString(strMiscWarning)); + exit(1); +} + int main(int argc, char *argv[]) { QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8")); @@ -197,9 +206,9 @@ int main(int argc, char *argv[]) return 1; } } catch (std::exception& e) { - PrintException(&e, "Runaway exception"); + handleRunawayException(&e); } catch (...) { - PrintException(NULL, "Runaway exception"); + handleRunawayException(NULL); } return 0; } From 401db6d96b34bbfa8942af1090ce29cafcf79859 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sun, 15 Apr 2012 11:42:40 +0200 Subject: [PATCH 13/20] work around issue in boost::program_options that prevents from compiling in clang --- src/util.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/util.cpp b/src/util.cpp index 0f496bc455a..c3290f4176d 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -4,6 +4,17 @@ // file license.txt or http://www.opensource.org/licenses/mit-license.php. #include "headers.h" #include "strlcpy.h" + +// Work around clang compilation problem in Boost 1.46: +// /usr/include/boost/program_options/detail/config_file.hpp:163:17: error: call to function 'to_internal' that is neither visible in the template definition nor found by argument-dependent lookup +// See also: http://stackoverflow.com/questions/10020179/compilation-fail-in-boost-librairies-program-options +// http://clang.debian.net/status.php?version=3.0&key=CANNOT_FIND_FUNCTION +namespace boost { + namespace program_options { + std::string to_internal(const std::string&); + } +} + #include #include #include From f650d62fc66d67e9afb6917de9220b1e0e6759fe Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sun, 15 Apr 2012 12:22:30 +0200 Subject: [PATCH 14/20] fix warnings: array subscript is of type 'char' [-Wchar-subscripts] --- src/bignum.h | 2 +- src/uint256.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bignum.h b/src/bignum.h index 6e8d3cb8aba..641ebf4b051 100644 --- a/src/bignum.h +++ b/src/bignum.h @@ -300,7 +300,7 @@ public: while (isxdigit(*psz)) { *this <<= 4; - int n = phexdigit[*psz++]; + int n = phexdigit[(unsigned char)*psz++]; *this += n; } if (fNegative) diff --git a/src/uint256.h b/src/uint256.h index ae263346a86..07809e49a8f 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -315,7 +315,7 @@ public: // hex string to uint static char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 }; const char* pbegin = psz; - while (phexdigit[*psz] || *psz == '0') + while (phexdigit[(unsigned char)*psz] || *psz == '0') psz++; psz--; unsigned char* p1 = (unsigned char*)pn; From 85e975f37907848ad28240da5b5e682ceb565eb2 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sun, 15 Apr 2012 12:22:30 +0200 Subject: [PATCH 15/20] fix warnings: array subscript is of type 'char' [-Wchar-subscripts] --- src/bignum.h | 2 +- src/uint256.h | 2 +- src/util.cpp | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/bignum.h b/src/bignum.h index 6e8d3cb8aba..641ebf4b051 100644 --- a/src/bignum.h +++ b/src/bignum.h @@ -300,7 +300,7 @@ public: while (isxdigit(*psz)) { *this <<= 4; - int n = phexdigit[*psz++]; + int n = phexdigit[(unsigned char)*psz++]; *this += n; } if (fNegative) diff --git a/src/uint256.h b/src/uint256.h index ae263346a86..07809e49a8f 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -315,7 +315,7 @@ public: // hex string to uint static char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 }; const char* pbegin = psz; - while (phexdigit[*psz] || *psz == '0') + while (phexdigit[(unsigned char)*psz] || *psz == '0') psz++; psz--; unsigned char* p1 = (unsigned char*)pn; diff --git a/src/util.cpp b/src/util.cpp index f6c37a2d1f3..a9111673e77 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -567,7 +567,7 @@ vector DecodeBase64(const char* p, bool* pfInvalid) while (1) { - int dec = decode64_table[*p]; + int dec = decode64_table[(unsigned char)*p]; if (dec == -1) break; p++; switch (mode) @@ -607,12 +607,12 @@ vector DecodeBase64(const char* p, bool* pfInvalid) break; case 2: // 4n+2 base64 characters processed: require '==' - if (left || p[0] != '=' || p[1] != '=' || decode64_table[p[2]] != -1) + if (left || p[0] != '=' || p[1] != '=' || decode64_table[(unsigned char)p[2]] != -1) *pfInvalid = true; break; case 3: // 4n+3 base64 characters processed: require '=' - if (left || p[0] != '=' || decode64_table[p[1]] != -1) + if (left || p[0] != '=' || decode64_table[(unsigned char)p[1]] != -1) *pfInvalid = true; break; } From c4381587a600fca2aba0ca4d45c7a5f14fc25c0f Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sun, 15 Apr 2012 12:31:56 +0200 Subject: [PATCH 16/20] fix warnings: 'XX' defined as a struct here but previously declared as a class [-Wmismatched-tags] --- src/qt/addresstablemodel.cpp | 3 ++- src/qt/transactiontablemodel.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index 8fd6d52b7e1..5d724ea1d10 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -27,8 +27,9 @@ struct AddressTableEntry }; // Private implementation -struct AddressTablePriv +class AddressTablePriv { +public: CWallet *wallet; QList cachedAddressTable; diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 480d4ac25e0..28620bf3aa2 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -45,8 +45,9 @@ struct TxLessThan }; // Private implementation -struct TransactionTablePriv +class TransactionTablePriv { +public: TransactionTablePriv(CWallet *wallet, TransactionTableModel *parent): wallet(wallet), parent(parent) From 5f4fee559e3a30d967b104ddadb82283788a9f8a Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sun, 15 Apr 2012 12:42:52 +0200 Subject: [PATCH 17/20] fix warnings: enumeration values 'XX' not handled in switch [-Wswitch-enum] --- src/qt/editaddressdialog.cpp | 3 +++ src/qt/sendcoinsdialog.cpp | 2 ++ src/qt/walletmodel.h | 3 +-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/qt/editaddressdialog.cpp b/src/qt/editaddressdialog.cpp index 8cc3c85d7ae..cecb8aecd79 100644 --- a/src/qt/editaddressdialog.cpp +++ b/src/qt/editaddressdialog.cpp @@ -106,6 +106,9 @@ void EditAddressDialog::accept() tr("New key generation failed."), QMessageBox::Ok, QMessageBox::Ok); return; + case AddressTableModel::OK: + // Failed with unknown reason. Just reject. + break; } return; diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 657761515b0..4c58b38b785 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -148,6 +148,8 @@ void SendCoinsDialog::on_sendButton_clicked() tr("Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."), QMessageBox::Ok, QMessageBox::Ok); break; + case WalletModel::Aborted: // User aborted, nothing to do + break; case WalletModel::OK: accept(); break; diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index 055ba184b0c..e04ae8790c0 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -34,8 +34,7 @@ public: DuplicateAddress, TransactionCreationFailed, // Error returned when wallet is still locked TransactionCommitFailed, - Aborted, - MiscError + Aborted }; enum EncryptionStatus From fdcafa35359b3ad9af79d2367a1884d01607fb84 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sun, 15 Apr 2012 12:53:14 +0200 Subject: [PATCH 18/20] fix warnings: unused variable 'XX' [-Wunused-variable] --- scripts/qt/extract_strings_qt.py | 12 +++++++++--- src/qt/bitcoinstrings.cpp | 7 ++++++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/scripts/qt/extract_strings_qt.py b/scripts/qt/extract_strings_qt.py index 6627de4abf4..b0478699eee 100755 --- a/scripts/qt/extract_strings_qt.py +++ b/scripts/qt/extract_strings_qt.py @@ -53,9 +53,15 @@ child = Popen(['xgettext','--output=-','-n','--keyword=_'] + files, stdout=PIPE) messages = parse_po(out) f = open(OUT_CPP, 'w') -f.write('#include \n') -f.write('// Automatically generated by extract_strings.py\n') -f.write('static const char *bitcoin_strings[] = {') +f.write("""#include +// Automatically generated by extract_strings.py +#ifdef __GNUC__ +#define UNUSED __attribute__((unused)) +#else +#define UNUSED +#endif +""") +f.write('static const char UNUSED *bitcoin_strings[] = {') for (msgid, msgstr) in messages: if msgid != EMPTY: f.write('QT_TRANSLATE_NOOP("bitcoin-core", %s),\n' % ('\n'.join(msgid))) diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp index 1b0a6767d78..2d77441b460 100644 --- a/src/qt/bitcoinstrings.cpp +++ b/src/qt/bitcoinstrings.cpp @@ -1,6 +1,11 @@ #include // Automatically generated by extract_strings.py -static const char *bitcoin_strings[] = {QT_TRANSLATE_NOOP("bitcoin-core", "Bitcoin version"), +#ifdef __GNUC__ +#define UNUSED __attribute__((unused)) +#else +#define UNUSED +#endif +static const char UNUSED *bitcoin_strings[] = {QT_TRANSLATE_NOOP("bitcoin-core", "Bitcoin version"), QT_TRANSLATE_NOOP("bitcoin-core", "Usage:"), QT_TRANSLATE_NOOP("bitcoin-core", "Send command to -server or bitcoind\n"), QT_TRANSLATE_NOOP("bitcoin-core", "List commands\n"), From 678a319888f88cf5bae2312afc3ba73533c0f901 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sun, 15 Apr 2012 12:59:20 +0200 Subject: [PATCH 19/20] fix warnings: delete called on 'XX' that has virtual functions but non-virtual destructor [-Wdelete-non-virtual-dtor] --- src/keystore.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/keystore.h b/src/keystore.h index 1f2c6aea3ea..cb297c35ab5 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -13,6 +13,8 @@ protected: mutable CCriticalSection cs_KeyStore; public: + virtual ~CKeyStore() {} + virtual bool AddKey(const CKey& key) =0; virtual bool HaveKey(const CBitcoinAddress &address) const =0; virtual bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const =0; From 8460185dec74383b1e49500683cfc7aa9ceba554 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sun, 15 Apr 2012 13:27:00 +0200 Subject: [PATCH 20/20] fix warnings: suggest explicit braces to avoid ambiguous 'else' [-Wparentheses] --- src/main.cpp | 4 ++++ src/main.h | 2 ++ src/rpc.cpp | 4 ++++ src/wallet.cpp | 2 ++ src/wallet.h | 2 ++ 5 files changed, 14 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 4316d242f9f..059dd3db9e0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1149,14 +1149,18 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex) // This rule applies to all blocks whose timestamp is after March 15, 2012, 0:00 UTC. // On testnet it is enabled as of februari 20, 2012, 0:00 UTC. if (pindex->nTime > 1331769600 || (fTestNet && pindex->nTime > 1329696000)) + { BOOST_FOREACH(CTransaction& tx, vtx) { CTxIndex txindexOld; if (txdb.ReadTxIndex(tx.GetHash(), txindexOld)) + { BOOST_FOREACH(CDiskTxPos &pos, txindexOld.vSpent) if (pos.IsNull()) return false; + } } + } // P2SH didn't become active until Apr 1 2012 (Feb 15 on testnet) int64 nEvalSwitchTime = fTestNet ? 1329264000 : 1333238400; diff --git a/src/main.h b/src/main.h index e6f60a6a8db..b0f713e876e 100644 --- a/src/main.h +++ b/src/main.h @@ -572,9 +572,11 @@ public: // To limit dust spam, require MIN_TX_FEE/MIN_RELAY_TX_FEE if any output is less than 0.01 if (nMinFee < nBaseFee) + { BOOST_FOREACH(const CTxOut& txout, vout) if (txout.nValue < CENT) nMinFee = nBaseFee; + } // Raise the price as the block approaches full if (nBlockSize != 1 && nNewBlockSize >= MAX_BLOCK_SIZE_GEN/2) diff --git a/src/rpc.cpp b/src/rpc.cpp index b62da8ecdf0..bbfea33d765 100644 --- a/src/rpc.cpp +++ b/src/rpc.cpp @@ -685,8 +685,10 @@ Value getbalance(const Array& params, bool fHelp) list > listSent; wtx.GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount); if (wtx.GetDepthInMainChain() >= nMinDepth) + { BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listReceived) nBalance += r.second; + } BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listSent) nBalance -= r.second; nBalance -= allFee; @@ -1046,6 +1048,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe // Received if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth) + { BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived) { string account; @@ -1063,6 +1066,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe ret.push_back(entry); } } + } } void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Array& ret) diff --git a/src/wallet.cpp b/src/wallet.cpp index 9f7422d1fbc..3f51313e9bf 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -545,8 +545,10 @@ void CWalletTx::AddSupportingTransactions(CTxDB& txdb) vtxPrev.push_back(tx); if (nDepth < COPY_DEPTH) + { BOOST_FOREACH(const CTxIn& txin, tx.vin) vWorkQueue.push_back(txin.prevout.hash); + } } } } diff --git a/src/wallet.h b/src/wallet.h index 4387e1a01fd..bb9177b6849 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -499,8 +499,10 @@ public: return false; if (mapPrev.empty()) + { BOOST_FOREACH(const CMerkleTx& tx, vtxPrev) mapPrev[tx.GetHash()] = &tx; + } BOOST_FOREACH(const CTxIn& txin, ptx->vin) {