Mercurial > hg > bitcoin
changeset 2916:5518e1ea4dd5 draft
Merge branch '0.5.0.x' into 0.5.x
author | Luke Dashjr <luke-jr+git@utopios.org> |
---|---|
date | Sun, 15 Apr 2012 21:06:10 -0400 |
parents | d23a41dbeca9 (current diff) 3b9ada19093d (diff) |
children | 162e3fdffc98 438eb06a9c9f |
files | src/bitcoinrpc.cpp src/qt/bitcoin.cpp src/qt/bitcoingui.cpp src/qt/walletmodel.h src/wallet.cpp src/wallet.h |
diffstat | 21 files changed, 133 insertions(+), 41 deletions(-) [+] |
line wrap: on
line diff
--- a/scripts/qt/extract_strings_qt.py +++ b/scripts/qt/extract_strings_qt.py @@ -53,9 +53,15 @@ messages = parse_po(out) f = open(OUT_CPP, 'w') -f.write('#include <QtGlobal>\n') -f.write('// Automatically generated by extract_strings.py\n') -f.write('static const char *bitcoin_strings[] = {') +f.write("""#include <QtGlobal> +// 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)))
old mode 100755 new mode 120000 --- a/scripts/qt/make_windows_icon.py +++ b/scripts/qt/make_windows_icon.py @@ -1,9 +1,1 @@ -#!/bin/bash -# create multiresolution windows icon -ICON_SRC=../../src/qt/res/icons/bitcoin.png -ICON_DST=../../src/qt/res/icons/bitcoin.ico -convert ${ICON_SRC} -resize 16x16 bitcoin-16.png -convert ${ICON_SRC} -resize 32x32 bitcoin-32.png -convert ${ICON_SRC} -resize 48x48 bitcoin-48.png -convert bitcoin-16.png bitcoin-32.png bitcoin-48.png ${ICON_DST} - +make_windows_icon.sh \ No newline at end of file
new file mode 100755 --- /dev/null +++ b/scripts/qt/make_windows_icon.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# create multiresolution windows icon +ICON_SRC=../../src/qt/res/icons/bitcoin.png +ICON_DST=../../src/qt/res/icons/bitcoin.ico +convert ${ICON_SRC} -resize 16x16 bitcoin-16.png +convert ${ICON_SRC} -resize 32x32 bitcoin-32.png +convert ${ICON_SRC} -resize 48x48 bitcoin-48.png +convert bitcoin-16.png bitcoin-32.png bitcoin-48.png ${ICON_DST} +
--- a/src/bignum.h +++ b/src/bignum.h @@ -300,7 +300,7 @@ while (isxdigit(*psz)) { *this <<= 4; - int n = phexdigit[*psz++]; + int n = phexdigit[(unsigned char)*psz++]; *this += n; } if (fNegative)
--- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -753,8 +753,10 @@ list<pair<CBitcoinAddress, int64> > 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; @@ -1112,6 +1114,7 @@ // Received if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth) + { BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived) { string account; @@ -1129,6 +1132,7 @@ ret.push_back(entry); } } + } } void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Array& ret) @@ -1165,14 +1169,21 @@ 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<CWalletTx*, CAccountingEntry*> TxPair; typedef multimap<int64, TxPair > 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<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { CWalletTx* wtx = &((*it).second); @@ -1185,10 +1196,8 @@ 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) @@ -1197,18 +1206,21 @@ 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; } @@ -2160,6 +2172,10 @@ printf("ThreadRPCServer exiting\n"); } +#ifdef QT_GUI +extern bool HACK_SHUTDOWN; +#endif + void ThreadRPCServer2(void* parg) { printf("ThreadRPCServer started\n"); @@ -2196,9 +2212,27 @@ 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);
--- a/src/keystore.h +++ b/src/keystore.h @@ -14,6 +14,8 @@ mutable CCriticalSection cs_KeyStore; public: + virtual ~CKeyStore() {} + // Add a key to the store. virtual bool AddKey(const CKey& key) =0;
--- a/src/main.cpp +++ b/src/main.cpp @@ -1169,14 +1169,18 @@ // 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;
--- a/src/main.h +++ b/src/main.h @@ -578,9 +578,11 @@ // 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)
--- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -27,8 +27,9 @@ }; // Private implementation -struct AddressTablePriv +class AddressTablePriv { +public: CWallet *wallet; QList<AddressTableEntry> cachedAddressTable;
--- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -120,6 +120,15 @@ 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")); @@ -205,9 +214,9 @@ return 1; } } catch (std::exception& e) { - PrintException(&e, "Runaway exception"); + handleRunawayException(&e); } catch (...) { - PrintException(NULL, "Runaway exception"); + handleRunawayException(NULL); } return 0; }
--- 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 @@ } // Set icon state: spinning if catching up, tick otherwise - if(secs < 90*60) + 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)); @@ -516,12 +519,16 @@ 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); }
--- a/src/qt/bitcoinstrings.cpp +++ b/src/qt/bitcoinstrings.cpp @@ -1,6 +1,11 @@ #include <QtGlobal> // 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"),
--- a/src/qt/editaddressdialog.cpp +++ b/src/qt/editaddressdialog.cpp @@ -106,6 +106,9 @@ tr("New key generation failed."), QMessageBox::Ok, QMessageBox::Ok); return; + case AddressTableModel::OK: + // Failed with unknown reason. Just reject. + break; } return;
--- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -278,7 +278,8 @@ 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();
--- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -148,6 +148,8 @@ 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;
--- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -45,8 +45,9 @@ }; // Private implementation -struct TransactionTablePriv +class TransactionTablePriv { +public: TransactionTablePriv(CWallet *wallet, TransactionTableModel *parent): wallet(wallet), parent(parent)
--- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -34,8 +34,7 @@ DuplicateAddress, TransactionCreationFailed, // Error returned when wallet is still locked TransactionCommitFailed, - Aborted, - MiscError + Aborted }; enum EncryptionStatus
--- a/src/uint256.h +++ b/src/uint256.h @@ -315,7 +315,7 @@ // 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;
--- 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 <boost/program_options/detail/config_file.hpp> #include <boost/program_options/parsers.hpp> #include <boost/filesystem.hpp> @@ -567,7 +578,7 @@ while (1) { - int dec = decode64_table[*p]; + int dec = decode64_table[(unsigned char)*p]; if (dec == -1) break; p++; switch (mode) @@ -607,12 +618,12 @@ 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; }