changeset 2824:288dba7c3905 draft

Merge branch '0.5.0.x' into 0.5.x Conflicts: bitcoin-qt.pro doc/README doc/README_windows.txt share/setup.nsi src/serialize.h
author Luke Dashjr <luke-jr+git@utopios.org>
date Fri, 16 Mar 2012 16:45:32 -0400
parents dab929825c24 (current diff) 700ef388ed93 (diff)
children 2724f0cddf58
files bitcoin-qt.pro doc/README doc/README_windows.txt share/setup.nsi src/bitcoinrpc.cpp src/qt/guiutil.h src/serialize.h
diffstat 10 files changed, 101 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/bitcoin-qt.pro
+++ b/bitcoin-qt.pro
@@ -251,8 +251,8 @@
     macx:BOOST_INCLUDE_PATH = /opt/local/include
 }
 
-windows:LIBS += -lws2_32
-windows:DEFINES += WIN32
+windows:LIBS += -lmingwthrd -lws2_32
+windows:DEFINES += _MT WIN32
 windows:RC_FILE = src/qt/res/bitcoin-qt.rc
 
 macx:HEADERS += src/qt/macdockiconhandler.h
--- a/contrib/gitian-descriptors/qt-win32.yml
+++ b/contrib/gitian-descriptors/qt-win32.yml
@@ -47,6 +47,7 @@
   cp -a bin $SRCDIR/
   cd $INSTDIR
   find . -name *.prl | xargs -l sed 's|/$||' -i
+  sed 's/QMAKE_LIBS_QT_ENTRY     = -lmingw32 -lqtmain/QMAKE_LIBS_QT_ENTRY     = -lqtmain/' -i mkspecs/unsupported/win32-g++-cross/qmake.conf
   #sed 's|QMAKE_PRL_LIBS.*|QMAKE_PRL_LIBS = -lQtDeclarative -lQtScript -lQtSvg -lQtSql -lQtXmlPatterns -lQtGui -lgdi32 -lcomdlg32 -loleaut32 -limm32 -lwinmm -lwinspool -lmsimg32 -lQtNetwork -lQtCore -lole32 -luuid -lws2_32 -ladvapi32 -lshell32 -luser32 -lkernel32|' -i imports/Qt/labs/particles/qmlparticlesplugin.prl
 
   # as zip stores file timestamps, use faketime to intercept stat calls to set dates for all files to reference date
--- a/src/bitcoinrpc.cpp
+++ b/src/bitcoinrpc.cpp
@@ -1658,7 +1658,7 @@
         }
 
         // Update nTime
-        pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
+        pblock->UpdateTime(pindexPrev);
         pblock->nNonce = 0;
 
         // Update nExtraNonce
@@ -1755,7 +1755,7 @@
         }
 
         // Update nTime
-        pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
+        pblock->UpdateTime(pindexPrev);
         pblock->nNonce = 0;
 
         Array transactions;
--- a/src/key.h
+++ b/src/key.h
@@ -290,13 +290,14 @@
 
     bool Sign(uint256 hash, std::vector<unsigned char>& vchSig)
     {
-        vchSig.clear();
-        unsigned char pchSig[10000];
-        unsigned int nSize = 0;
-        if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), pchSig, &nSize, pkey))
+        unsigned int nSize = ECDSA_size(pkey);
+        vchSig.resize(nSize); // Make sure it is big enough
+        if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], &nSize, pkey))
+        {
+            vchSig.clear();
             return false;
-        vchSig.resize(nSize);
-        memcpy(&vchSig[0], pchSig, nSize);
+        }
+        vchSig.resize(nSize); // Shrink to fit actual size
         return true;
     }
 
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -820,6 +820,15 @@
         printf("InvalidChainFound: WARNING: Displayed transactions may not be correct!  You may need to upgrade, or other nodes may need to upgrade.\n");
 }
 
+void CBlock::UpdateTime(const CBlockIndex* pindexPrev)
+{
+    nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
+
+    // Updating time can change work required on testnet:
+    if (fTestNet)
+        nBits = GetNextWorkRequired(pindexPrev, this);
+}
+
 
 
 
@@ -1950,7 +1959,7 @@
         }
 
         // Ask the first connected node for block updates
-        static int nAskedForBlocks;
+        static int nAskedForBlocks = 0;
         if (!pfrom->fClient &&
             (pfrom->nVersion < 32000 || pfrom->nVersion >= 32400) &&
              (nAskedForBlocks < 1 || vNodes.size() <= 1))
@@ -2949,7 +2958,7 @@
     // Fill in header
     pblock->hashPrevBlock  = pindexPrev->GetBlockHash();
     pblock->hashMerkleRoot = pblock->BuildMerkleTree();
-    pblock->nTime          = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
+    pblock->UpdateTime(pindexPrev);
     pblock->nBits          = GetNextWorkRequired(pindexPrev, pblock.get());
     pblock->nNonce         = 0;
 
@@ -3105,6 +3114,7 @@
         FormatHashBuffers(pblock.get(), pmidstate, pdata, phash1);
 
         unsigned int& nBlockTime = *(unsigned int*)(pdata + 64 + 4);
+        unsigned int& nBlockBits = *(unsigned int*)(pdata + 64 + 8);
         unsigned int& nBlockNonce = *(unsigned int*)(pdata + 64 + 12);
 
 
@@ -3192,8 +3202,14 @@
                 break;
 
             // Update nTime every few seconds
-            pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
+            pblock->UpdateTime(pindexPrev);
             nBlockTime = ByteReverse(pblock->nTime);
+            if (fTestNet)
+            {
+                // Changing pblock->nTime can change work required on testnet:
+                nBlockBits = ByteReverse(pblock->nBits);
+                hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
+            }
         }
     }
 }
--- a/src/main.h
+++ b/src/main.h
@@ -856,6 +856,8 @@
         return n;
     }
 
+    void UpdateTime(const CBlockIndex* pindexPrev);
+
 
     uint256 BuildMerkleTree() const
     {
--- a/src/qt/addressbookpage.cpp
+++ b/src/qt/addressbookpage.cpp
@@ -7,7 +7,6 @@
 
 #include <QSortFilterProxyModel>
 #include <QClipboard>
-#include <QFileDialog>
 #include <QMessageBox>
 
 AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) :
@@ -206,10 +205,9 @@
 void AddressBookPage::exportClicked()
 {
     // CSV is currently the only supported format
-    QString filename = QFileDialog::getSaveFileName(
+    QString filename = GUIUtil::getSaveFileName(
             this,
-            tr("Export Address Book Data"),
-            QDir::currentPath(),
+            tr("Export Address Book Data"), QString(),
             tr("Comma separated file (*.csv)"));
 
     if (filename.isNull()) return;
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -11,6 +11,8 @@
 #include <QFont>
 #include <QLineEdit>
 #include <QUrl>
+#include <QFileDialog>
+#include <QDesktopServices>
 
 QString GUIUtil::dateTimeStr(qint64 nTime)
 {
@@ -86,3 +88,50 @@
     QUrl urlInstance(url);
     return parseBitcoinURL(&urlInstance, out);
 }
+
+QString GUIUtil::getSaveFileName(QWidget *parent, const QString &caption,
+                                 const QString &dir,
+                                 const QString &filter,
+                                 QString *selectedSuffixOut)
+{
+    QString selectedFilter;
+    QString myDir;
+    if(dir.isEmpty()) // Default to user documents location
+    {
+        myDir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation);
+    }
+    else
+    {
+        myDir = dir;
+    }
+    QString result = QFileDialog::getSaveFileName(parent, caption, myDir, filter, &selectedFilter);
+
+    /* Extract first suffix from filter pattern "Description (*.foo)" or "Description (*.foo *.bar ...) */
+    QRegExp filter_re(".* \\(\\*\\.(.*)[ \\)]");
+    QString selectedSuffix;
+    if(filter_re.exactMatch(selectedFilter))
+    {
+        selectedSuffix = filter_re.cap(1);
+    }
+
+    /* Add suffix if needed */
+    QFileInfo info(result);
+    if(!result.isEmpty())
+    {
+        if(info.suffix().isEmpty() && !selectedSuffix.isEmpty())
+        {
+            /* No suffix specified, add selected suffix */
+            if(!result.endsWith("."))
+                result.append(".");
+            result.append(selectedSuffix);
+        }
+    }
+
+    /* Return selected suffix if asked to */
+    if(selectedSuffixOut)
+    {
+        *selectedSuffixOut = selectedSuffix;
+    }
+    return result;
+}
+
--- a/src/qt/guiutil.h
+++ b/src/qt/guiutil.h
@@ -32,6 +32,21 @@
     // 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);
+
+    /** Get save file name, mimics QFileDialog::getSaveFileName, except that it appends a default suffix
+        when no suffix is provided by the user.
+
+      @param[in] parent  Parent window (or 0)
+      @param[in] caption Window caption (or empty, for default)
+      @param[in] dir     Starting directory (or empty, to default to documents directory)
+      @param[in] filter  Filter specification such as "Comma Separated Files (*.csv)"
+      @param[out] selectedSuffixOut  Pointer to return the suffix (file type) that was selected (or 0).
+                  Can be useful when choosing the save file format based on suffix.
+     */
+    static QString getSaveFileName(QWidget *parent=0, const QString &caption=QString(),
+                                   const QString &dir=QString(), const QString &filter=QString(),
+                                   QString *selectedSuffixOut=0);
+
 };
 
 #endif // GUIUTIL_H
--- a/src/qt/transactionview.cpp
+++ b/src/qt/transactionview.cpp
@@ -20,7 +20,6 @@
 #include <QTableView>
 #include <QHeaderView>
 #include <QPushButton>
-#include <QFileDialog>
 #include <QMessageBox>
 #include <QPoint>
 #include <QMenu>
@@ -265,10 +264,9 @@
 void TransactionView::exportClicked()
 {
     // CSV is currently the only supported format
-    QString filename = QFileDialog::getSaveFileName(
+    QString filename = GUIUtil::getSaveFileName(
             this,
-            tr("Export Transaction Data"),
-            QDir::currentPath(),
+            tr("Export Transaction Data"), QString(),
             tr("Comma separated file (*.csv)"));
 
     if (filename.isNull()) return;