Merge pull request #226 from jordanlewis/betterheaders
authorJeff Garzik <jgarzik@exmulti.com>
Tue, 14 Jun 2011 09:05:57 +0000 (02:05 -0700)
committerJeff Garzik <jgarzik@exmulti.com>
Tue, 14 Jun 2011 09:05:57 +0000 (02:05 -0700)
Optimize header dependencies; improve Makefile dependency graph

1  2 
src/db.cpp
src/init.cpp
src/irc.cpp
src/main.cpp
src/main.h
src/net.cpp
src/rpc.cpp
src/ui.cpp
src/util.cpp
src/util.h

diff --combined src/db.cpp
@@@ -3,6 -3,9 +3,9 @@@
  // file license.txt or http://www.opensource.org/licenses/mit-license.php.
  
  #include "headers.h"
+ #include "db.h"
+ #include "net.h"
+ #include <boost/filesystem/fstream.hpp>
  
  using namespace std;
  using namespace boost;
@@@ -845,11 -848,12 +848,11 @@@ bool LoadWallet(bool& fFirstRunRet
      {
          // Create new keyUser and set as default key
          RandAddSeedPerfmon();
 -        keyUser.MakeNewKey();
 -        if (!AddKey(keyUser))
 -            return false;
 -        if (!SetAddressBookName(PubKeyToAddress(keyUser.GetPubKey()), ""))
 -            return false;
 -        CWalletDB().WriteDefaultKey(keyUser.GetPubKey());
 +
 +        CWalletDB walletdb;
 +        vchDefaultKey = GetKeyFromKeyPool();
 +        walletdb.WriteDefaultKey(vchDefaultKey);
 +        walletdb.WriteName(PubKeyToAddress(vchDefaultKey), "");
      }
  
      CreateThread(ThreadFlushWalletDB, NULL);
diff --combined src/init.cpp
@@@ -2,6 -2,13 +2,13 @@@
  // Distributed under the MIT/X11 software license, see the accompanying
  // file license.txt or http://www.opensource.org/licenses/mit-license.php.
  #include "headers.h"
+ #include "db.h"
+ #include "rpc.h"
+ #include "net.h"
+ #include "init.h"
+ #include "strlcpy.h"
+ #include <boost/filesystem/fstream.hpp>
+ #include <boost/interprocess/sync/file_lock.hpp>
  
  using namespace std;
  using namespace boost;
@@@ -137,6 -144,7 +144,6 @@@ bool AppInit2(int argc, char* argv[]
  
      if (mapArgs.count("-?") || mapArgs.count("--help"))
      {
 -        string beta = VERSION_IS_BETA ? _(" beta") : "";
          string strUsage = string() +
            _("Bitcoin version") + " " + FormatFullVersion() + "\n\n" +
            _("Usage:") + "\t\t\t\t\t\t\t\t\t\t\n" +
              "  -gen=0           \t\t  " + _("Don't generate coins\n") +
              "  -min             \t\t  " + _("Start minimized\n") +
              "  -datadir=<dir>   \t\t  " + _("Specify data directory\n") +
 +            "  -timeout=<n>     \t  "   + _("Specify connection timeout (in milliseconds)\n") +
              "  -proxy=<ip:port> \t  "   + _("Connect through socks4 proxy\n") +
              "  -dns             \t  "   + _("Allow DNS lookups for addnode and connect\n") +
              "  -addnode=<ip>    \t  "   + _("Add a node to connect to\n") +
      {
          printf("Rescanning last %i blocks (from block %i)...\n", pindexBest->nHeight - pindexRescan->nHeight, pindexRescan->nHeight);
          nStart = GetTimeMillis();
 -        ScanForWalletTransactions(pindexRescan);
 +        ScanForWalletTransactions(pindexRescan, true);
          printf(" rescan      %15"PRI64d"ms\n", GetTimeMillis() - nStart);
      }
  
          return false;
      }
  
 +    if (mapArgs.count("-timeout"))
 +    {
 +        int nNewTimeout = GetArg("-timeout", 5000);
 +        if (nNewTimeout > 0 && nNewTimeout < 600000)
 +            nConnectTimeout = nNewTimeout;
 +    }
 +
      if (mapArgs.count("-printblock"))
      {
          string strMatch = mapArgs["-printblock"];
diff --combined src/irc.cpp
@@@ -3,6 -3,9 +3,9 @@@
  // file license.txt or http://www.opensource.org/licenses/mit-license.php.
  
  #include "headers.h"
+ #include "irc.h"
+ #include "net.h"
+ #include "strlcpy.h"
  
  using namespace std;
  using namespace boost;
@@@ -265,11 -268,11 +268,11 @@@ void ThreadIRCSeed2(void* parg
      while (!fShutdown)
      {
          //CAddress addrConnect("216.155.130.130:6667"); // chat.freenode.net
 -        CAddress addrConnect("92.243.23.21:6667"); // irc.lfnet.org
 +        CAddress addrConnect("92.243.23.21", 6667); // irc.lfnet.org
          if (!fTOR)
          {
              //struct hostent* phostent = gethostbyname("chat.freenode.net");
 -            CAddress addrIRC("irc.lfnet.org:6667", 0, true);
 +            CAddress addrIRC("irc.lfnet.org", 6667, true);
              if (addrIRC.IsValid())
                  addrConnect = addrIRC;
          }
                  Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str());
              }
          }
 -
 -        Send(hSocket, fTestNet ? "JOIN #bitcoinTEST\r" : "JOIN #bitcoin\r");
 -        Send(hSocket, fTestNet ? "WHO #bitcoinTEST\r"  : "WHO #bitcoin\r");
 +        
 +        if (fTestNet) {
 +            Send(hSocket, "JOIN #bitcoinTEST\r");
 +            Send(hSocket, "WHO #bitcoinTEST\r");
 +        } else {
 +            // randomly join #bitcoin00-#bitcoin99
 +            int channel_number = GetRandInt(100);
 +            Send(hSocket, strprintf("JOIN #bitcoin%02d\r", channel_number).c_str());
 +            Send(hSocket, strprintf("WHO #bitcoin%02d\r", channel_number).c_str());
 +        }
  
          int64 nStart = GetTime();
          string strLine;
diff --combined src/main.cpp
@@@ -2,7 -2,11 +2,11 @@@
  // Distributed under the MIT/X11 software license, see the accompanying
  // file license.txt or http://www.opensource.org/licenses/mit-license.php.
  #include "headers.h"
+ #include "db.h"
+ #include "net.h"
+ #include "init.h"
  #include "cryptopp/sha.h"
+ #include <boost/filesystem/fstream.hpp>
  
  using namespace std;
  using namespace boost;
@@@ -731,13 -735,13 +735,13 @@@ bool CTransaction::AcceptToMemoryPool(C
          }
  
          // Don't accept it if it can't get into a block
 -        if (nFees < GetMinFee(1000))
 +        if (nFees < GetMinFee(1000, true, true))
              return error("AcceptToMemoryPool() : not enough fees");
  
          // Continuously rate-limit free transactions
          // This mitigates 'penny-flooding' -- sending thousands of free transactions just to
          // be annoying or make other's transactions take longer to confirm.
 -        if (nFees < MIN_TX_FEE)
 +        if (nFees < MIN_RELAY_TX_FEE)
          {
              static CCriticalSection cs;
              static double dFreeCount;
@@@ -884,7 -888,7 +888,7 @@@ bool CWalletTx::AcceptWalletTransaction
      return false;
  }
  
 -int ScanForWalletTransactions(CBlockIndex* pindexStart)
 +int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
  {
      int ret = 0;
  
              block.ReadFromDisk(pindex, true);
              BOOST_FOREACH(CTransaction& tx, block.vtx)
              {
 -                if (AddToWalletIfInvolvingMe(tx, &block))
 +                if (AddToWalletIfInvolvingMe(tx, &block, fUpdate))
                      ret++;
              }
              pindex = pindex->pnext;
@@@ -3329,7 -3333,7 +3333,7 @@@ CBlock* CreateNewBlock(CReserveKey& res
  
              // Transaction fee required depends on block size
              bool fAllowFree = (nBlockSize + nTxSize < 4000 || CTransaction::AllowFree(dPriority));
 -            int64 nMinFee = tx.GetMinFee(nBlockSize, fAllowFree);
 +            int64 nMinFee = tx.GetMinFee(nBlockSize, fAllowFree, true);
  
              // Connecting shouldn't fail due to dependency on other memory pool transactions
              // because we're already processing them in order of dependency
@@@ -3854,18 -3858,9 +3858,18 @@@ bool CreateTransaction(const vector<pai
                      dPriority += (double)nCredit * pcoin.first->GetDepthInMainChain();
                  }
  
 -                // Fill a vout back to self with any change
 -                int64 nChange = nValueIn - nTotalValue;
 -                if (nChange >= CENT)
 +                int64 nChange = nValueIn - nValue - nFeeRet;
 +
 +                // if sub-cent change is required, the fee must be raised to at least MIN_TX_FEE
 +                // or until nChange becomes zero
 +                if (nFeeRet < MIN_TX_FEE && nChange > 0 && nChange < CENT)
 +                {
 +                    int64 nMoveToFee = min(nChange, MIN_TX_FEE - nFeeRet);
 +                    nChange -= nMoveToFee;
 +                    nFeeRet += nMoveToFee;
 +                }
 +
 +                if (nChange > 0)
                  {
                      // Note: We use a new key here to keep it from being obvious which side is the change.
                      //  The drawback is that by not reusing a previous key, the change may be lost if a
diff --combined src/main.h
@@@ -24,13 -24,19 +24,20 @@@ class CBlockIndex
  class CWalletTx;
  class CKeyItem;
  
+ class CMessageHeader;
+ class CAddress;
+ class CInv;
+ class CRequestTracker;
+ class CNode;
+ class CBlockIndex;
  static const unsigned int MAX_BLOCK_SIZE = 1000000;
  static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2;
  static const int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
  static const int64 COIN = 100000000;
  static const int64 CENT = 1000000;
  static const int64 MIN_TX_FEE = 50000;
 +static const int64 MIN_RELAY_TX_FEE = 10000;
  static const int64 MAX_MONEY = 21000000 * COIN;
  inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }
  static const int COINBASE_MATURITY = 100;
@@@ -78,7 -84,11 +85,10 @@@ extern int fUseUPnP
  
  
  
+ class CReserveKey;
+ class CTxDB;
+ class CTxIndex;
  
 -
  bool CheckDiskSpace(uint64 nAdditionalBytes=0);
  FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb");
  FILE* AppendBlockFile(unsigned int& nFileRet);
@@@ -86,7 -96,7 +96,7 @@@ bool AddKey(const CKey& key)
  std::vector<unsigned char> GenerateNewKey();
  bool AddToWallet(const CWalletTx& wtxIn);
  void WalletUpdateSpent(const COutPoint& prevout);
 -int ScanForWalletTransactions(CBlockIndex* pindexStart);
 +int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false);
  void ReacceptWalletTransactions();
  bool LoadBlockIndex(bool fAllowNew=true);
  void PrintBlockTree();
@@@ -599,14 -609,12 +609,14 @@@ public
          return dPriority > COIN * 144 / 250;
      }
  
 -    int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=true) const
 +    int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=true, bool fForRelay=false) const
      {
 -        // Base fee is 1 cent per kilobyte
 +        // Base fee is either MIN_TX_FEE or MIN_RELAY_TX_FEE
 +        int64 nBaseFee = fForRelay ? MIN_RELAY_TX_FEE : MIN_TX_FEE;
 +
          unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK);
          unsigned int nNewBlockSize = nBlockSize + nBytes;
 -        int64 nMinFee = (1 + (int64)nBytes / 1000) * MIN_TX_FEE;
 +        int64 nMinFee = (1 + (int64)nBytes / 1000) * nBaseFee;
  
          if (fAllowFree)
          {
              }
          }
  
 -        // To limit dust spam, require MIN_TX_FEE if any output is less than 0.01
 -        if (nMinFee < MIN_TX_FEE)
 +        // 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 = MIN_TX_FEE;
 +                    nMinFee = nBaseFee;
  
          // Raise the price as the block approaches full
          if (nBlockSize != 1 && nNewBlockSize >= MAX_BLOCK_SIZE_GEN/2)
diff --combined src/net.cpp
@@@ -3,6 -3,11 +3,11 @@@
  // file license.txt or http://www.opensource.org/licenses/mit-license.php.
  
  #include "headers.h"
+ #include "irc.h"
+ #include "db.h"
+ #include "net.h"
+ #include "init.h"
+ #include "strlcpy.h"
  
  #ifdef USE_UPNP
  #include <miniupnpc/miniwget.h>
@@@ -51,16 -56,11 +56,16 @@@ map<CInv, int64> mapAlreadyAskedFor
  
  // Settings
  int fUseProxy = false;
 +int nConnectTimeout = 5000;
  CAddress addrProxy("127.0.0.1",9050);
  
  
  
  
 +unsigned short GetListenPort()
 +{
 +    return (unsigned short)(GetArg("-port", GetDefaultPort()));
 +}
  
  void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
  {
@@@ -77,7 -77,7 +82,7 @@@
  
  
  
 -bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet)
 +bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout)
  {
      hSocketRet = INVALID_SOCKET;
  
      setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
  #endif
  
 -    bool fRoutable = !(addrConnect.GetByte(3) == 10 || (addrConnect.GetByte(3) == 192 && addrConnect.GetByte(2) == 168));
 -    bool fProxy = (fUseProxy && fRoutable);
 +    bool fProxy = (fUseProxy && addrConnect.IsRoutable());
      struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
  
 +#ifdef __WXMSW__
 +    u_long fNonblock = 1;
 +    if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
 +#else
 +    int fFlags = fcntl(hSocket, F_GETFL, 0);
 +    if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1)
 +#endif
 +    {
 +        closesocket(hSocket);
 +        return false;
 +    }
 +
 +
      if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
      {
 +        // WSAEINVAL is here because some legacy version of winsock uses it
 +        if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL)
 +        {
 +            struct timeval timeout;
 +            timeout.tv_sec  = nTimeout / 1000;
 +            timeout.tv_usec = (nTimeout % 1000) * 1000;
 +
 +            fd_set fdset;
 +            FD_ZERO(&fdset);
 +            FD_SET(hSocket, &fdset);
 +            int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout);
 +            if (nRet == 0)
 +            {
 +                printf("connection timeout\n");
 +                closesocket(hSocket);
 +                return false;
 +            }
 +            if (nRet == SOCKET_ERROR)
 +            {
 +                printf("select() for connection failed: %i\n",WSAGetLastError());
 +                closesocket(hSocket);
 +                return false;
 +            }
 +            socklen_t nRetSize = sizeof(nRet);
 +#ifdef __WXMSW__
 +            if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (char*)(&nRet), &nRetSize) == SOCKET_ERROR)
 +#else
 +            if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR)
 +#endif
 +            {
 +                printf("getsockopt() for connection failed: %i\n",WSAGetLastError());
 +                closesocket(hSocket);
 +                return false;
 +            }
 +            if (nRet != 0)
 +            {
 +                printf("connect() failed after select(): %i\n",nRet);
 +                closesocket(hSocket);
 +                return false;
 +            }
 +        }
 +#ifdef __WXMSW__
 +        else if (WSAGetLastError() != WSAEISCONN)
 +#else
 +        else
 +#endif
 +        {
 +            printf("connect() failed: %s\n",WSAGetLastError());
 +            closesocket(hSocket);
 +            return false;
 +        }
 +    }
 +
 +    /*
 +    this isn't even strictly necessary
 +    CNode::ConnectNode immediately turns the socket back to non-blocking
 +    but we'll turn it back to blocking just in case
 +    */
 +#ifdef __WXMSW__
 +    fNonblock = 0;
 +    if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
 +#else
 +    fFlags = fcntl(hSocket, F_GETFL, 0);
 +    if (fcntl(hSocket, F_SETFL, fFlags & !O_NONBLOCK) == SOCKET_ERROR)
 +#endif
 +    {
          closesocket(hSocket);
          return false;
      }
@@@ -836,12 -758,9 +841,12 @@@ void ThreadSocketHandler2(void* parg
          if (nSelect == SOCKET_ERROR)
          {
              int nErr = WSAGetLastError();
 -            printf("socket select error %d\n", nErr);
 -            for (int i = 0; i <= hSocketMax; i++)
 -                FD_SET(i, &fdsetRecv);
 +            if (hSocketMax > -1)
 +            {
 +                printf("socket select error %d\n", nErr);
 +                for (int i = 0; i <= hSocketMax; i++)
 +                    FD_SET(i, &fdsetRecv);
 +            }
              FD_ZERO(&fdsetSend);
              FD_ZERO(&fdsetError);
              Sleep(timeout.tv_usec/1000);
@@@ -1051,7 -970,7 +1056,7 @@@ void ThreadMapPort2(void* parg
      printf("ThreadMapPort started\n");
  
      char port[6];
 -    sprintf(port, "%d", GetDefaultPort());
 +    sprintf(port, "%d", GetListenPort());
  
      const char * rootdescurl = 0;
      const char * multicastif = 0;
@@@ -1144,7 -1063,7 +1149,7 @@@ void DNSAddressSeed(
  
      for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
          vector<CAddress> vaddr;
 -        if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, true))
 +        if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, -1, true))
          {
              BOOST_FOREACH (CAddress& addr, vaddr)
              {
@@@ -1521,11 -1440,14 +1526,11 @@@ void ThreadMessageHandler2(void* parg
  
  
  
 -
 -
 -
  bool BindListenPort(string& strError)
  {
      strError = "";
      int nOne = 1;
 -    addrLocalHost.port = htons(GetDefaultPort());
 +    addrLocalHost.port = htons(GetListenPort());
  
  #ifdef __WXMSW__
      // Initialize Windows Sockets
      memset(&sockaddr, 0, sizeof(sockaddr));
      sockaddr.sin_family = AF_INET;
      sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
 -    sockaddr.sin_port = htons(GetDefaultPort());
 +    sockaddr.sin_port = htons(GetListenPort());
      if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
      {
          int nErr = WSAGetLastError();
@@@ -1639,7 -1561,7 +1644,7 @@@ void StartNode(void* parg
                      printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
  
                  // Take the first IP that isn't loopback 127.x.x.x
 -                CAddress addr(*(unsigned int*)&s4->sin_addr, 0, nLocalServices);
 +                CAddress addr(*(unsigned int*)&s4->sin_addr, GetListenPort(), nLocalServices);
                  if (addr.IsValid() && addr.GetByte(3) != 127)
                  {
                      addrLocalHost = addr;
diff --combined src/rpc.cpp
@@@ -4,12 -4,17 +4,17 @@@
  
  #include "headers.h"
  #include "cryptopp/sha.h"
+ #include "db.h"
+ #include "net.h"
+ #include "init.h"
  #undef printf
  #include <boost/asio.hpp>
  #include <boost/iostreams/concepts.hpp>
  #include <boost/iostreams/stream.hpp>
+ #include <boost/algorithm/string.hpp>
  #ifdef USE_SSL
  #include <boost/asio/ssl.hpp> 
+ #include <boost/filesystem/fstream.hpp>
  typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> SSLStream;
  #endif
  #include "json/json_spirit_reader_template.h"
@@@ -199,26 -204,12 +204,26 @@@ double GetDifficulty(
  {
      // Floating point number that is a multiple of the minimum difficulty,
      // minimum difficulty = 1.0.
 +
      if (pindexBest == NULL)
          return 1.0;
 -    int nShift = 256 - 32 - 31; // to fit in a uint
 -    double dMinimum = (CBigNum().SetCompact(bnProofOfWorkLimit.GetCompact()) >> nShift).getuint();
 -    double dCurrently = (CBigNum().SetCompact(pindexBest->nBits) >> nShift).getuint();
 -    return dMinimum / dCurrently;
 +    int nShift = (pindexBest->nBits >> 24) & 0xff;
 +
 +    double dDiff =
 +        (double)0x0000ffff / (double)(pindexBest->nBits & 0x00ffffff);
 +
 +    while (nShift < 29)
 +    {
 +        dDiff *= 256.0;
 +        nShift++;
 +    }
 +    while (nShift > 29)
 +    {
 +        dDiff /= 256.0;
 +        nShift--;
 +    }
 +
 +    return dDiff;
  }
  
  Value getdifficulty(const Array& params, bool fHelp)
diff --combined src/ui.cpp
@@@ -3,6 -3,10 +3,10 @@@
  // file license.txt or http://www.opensource.org/licenses/mit-license.php.
  
  #include "headers.h"
+ #include "init.h"
+ #include "strlcpy.h"
+ #include <boost/filesystem/fstream.hpp>
+ #include <boost/filesystem/convenience.hpp>
  #ifdef _MSC_VER
  #include <crtdbg.h>
  #endif
@@@ -18,13 -22,6 +22,13 @@@ CMyTaskBarIcon* ptaskbaricon = NULL
  bool fClosedToTray = false;
  wxLocale g_locale;
  
 +#ifdef __WXMSW__
 +double nScaleX = 1.0;
 +double nScaleY = 1.0;
 +#else
 +static const double nScaleX = 1.0;
 +static const double nScaleY = 1.0;
 +#endif
  
  
  
@@@ -270,10 -267,9 +274,10 @@@ CMainFrame::CMainFrame(wxWindow* parent
      fOnSetFocusAddress = false;
      fRefresh = false;
      m_choiceFilter->SetSelection(0);
 -    double dResize = 1.0;
 +    double dResize = nScaleX;
  #ifdef __WXMSW__
      SetIcon(wxICON(bitcoin));
 +    SetSize(dResize * GetSize().GetWidth(), nScaleY * GetSize().GetHeight());
  #else
      SetIcon(bitcoin80_xpm);
      SetBackgroundColour(m_toolBar->GetBackgroundColour());
@@@ -1227,9 -1223,6 +1231,9 @@@ void CMainFrame::OnListItemActivated(wx
  
  CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetailsDialogBase(parent)
  {
 +#ifdef __WXMSW__
 +    SetSize(nScaleX * GetSize().GetWidth(), nScaleY * GetSize().GetHeight());
 +#endif
      CRITICAL_BLOCK(cs_mapAddressBook)
      {
          string strHTML;
@@@ -1644,8 -1637,6 +1648,8 @@@ COptionsDialog::COptionsDialog(wxWindow
      SelectPage(0);
  #ifndef __WXMSW__
      SetSize(1.0 * GetSize().GetWidth(), 1.2 * GetSize().GetHeight());
 +#else
 +    SetSize(nScaleX * GetSize().GetWidth(), nScaleY * GetSize().GetHeight());
  #endif
  #if defined(__WXGTK__) || defined(__WXMAC_OSX__)
      m_checkBoxStartOnSystemStartup->SetLabel(_("&Start Bitcoin on window system startup"));
@@@ -1816,8 -1807,6 +1820,8 @@@ CAboutDialog::CAboutDialog(wxWindow* pa
          fontTmp.SetPointSize(8);
      m_staticTextMain->SetFont(fontTmp);
      SetSize(GetSize().GetWidth() + 44, GetSize().GetHeight() + 10);
 +#else
 +    SetSize(nScaleX * GetSize().GetWidth(), nScaleY * GetSize().GetHeight());
  #endif
  }
  
@@@ -1852,21 -1841,12 +1856,21 @@@ CSendDialog::CSendDialog(wxWindow* pare
          fontTmp.SetPointSize(9);
      m_staticTextInstructions->SetFont(fontTmp);
      SetSize(725, 180);
 +#else
 +    SetSize(nScaleX * GetSize().GetWidth(), nScaleY * GetSize().GetHeight());
  #endif
      
      // Set Icon
 -    wxIcon iconSend;
 -    iconSend.CopyFromBitmap(wxBitmap(send16noshadow_xpm));
 -    SetIcon(iconSend);
 +    if (nScaleX == 1.0 && nScaleY == 1.0) // We don't have icons of the proper size otherwise
 +    {
 +        wxIcon iconSend;
 +        iconSend.CopyFromBitmap(wxBitmap(send16noshadow_xpm));
 +        SetIcon(iconSend);
 +    }
 +#ifdef __WXMSW__
 +    else
 +        SetIcon(wxICON(bitcoin));
 +#endif
  
      // Fixup the tab order
      m_buttonPaste->MoveAfterInTabOrder(m_buttonCancel);
@@@ -2016,8 -1996,6 +2020,8 @@@ CSendingDialog::CSendingDialog(wxWindow
      fWorkDone = false;
  #ifndef __WXMSW__
      SetSize(1.2 * GetSize().GetWidth(), 1.08 * GetSize().GetHeight());
 +#else
 +    SetSize(nScaleX * GetSize().GetWidth(), nScaleY * GetSize().GetHeight());
  #endif
  
      SetTitle(strprintf(_("Sending %s to %s"), FormatMoney(nPrice).c_str(), wtx.mapValue["to"].c_str()));
@@@ -2341,10 -2319,6 +2345,10 @@@ void CSendingDialog::OnReply3(CDataStre
  
  CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, int nPageIn, bool fDuringSendIn) : CAddressBookDialogBase(parent)
  {
 +#ifdef __WXMSW__
 +    SetSize(nScaleX * GetSize().GetWidth(), nScaleY * GetSize().GetHeight());
 +#endif
 +
      // Set initially selected page
      wxNotebookEvent event;
      event.SetSelection(nPageIn);
          m_buttonCancel->Show(false);
  
      // Set Icon
 -    wxIcon iconAddressBook;
 -    iconAddressBook.CopyFromBitmap(wxBitmap(addressbook16_xpm));
 -    SetIcon(iconAddressBook);
 +    if (nScaleX == 1.0 && nScaleY == 1.0) // We don't have icons of the proper size otherwise
 +    {
 +        wxIcon iconAddressBook;
 +        iconAddressBook.CopyFromBitmap(wxBitmap(addressbook16_xpm));
 +        SetIcon(iconAddressBook);
 +    }
 +#ifdef __WXMSW__
 +    else
 +        SetIcon(wxICON(bitcoin));
 +#endif
  
      // Init column headers
      m_listCtrlSending->InsertColumn(0, _("Name"), wxLIST_FORMAT_LEFT, 200);
@@@ -2881,16 -2848,6 +2885,16 @@@ bool CMyApp::OnInit(
      g_locale.AddCatalog("wxstd"); // wxWidgets standard translations, if any
      g_locale.AddCatalog("bitcoin");
  
 +#ifdef __WXMSW__
 +    HDC hdc = GetDC(NULL);
 +    if (hdc)
 +    {
 +        nScaleX = GetDeviceCaps(hdc, LOGPIXELSX) / 96.0;
 +        nScaleY = GetDeviceCaps(hdc, LOGPIXELSY) / 96.0;
 +        ReleaseDC(NULL, hdc);
 +    }
 +#endif
 +
      return AppInit(argc, argv);
  }
  
diff --combined src/util.cpp
@@@ -2,6 -2,13 +2,13 @@@
  // Distributed under the MIT/X11 software license, see the accompanying
  // file license.txt or http://www.opensource.org/licenses/mit-license.php.
  #include "headers.h"
+ #include "strlcpy.h"
+ #include <boost/program_options/detail/config_file.hpp>
+ #include <boost/program_options/parsers.hpp>
+ #include <boost/filesystem/fstream.hpp>
+ #include <boost/interprocess/sync/interprocess_mutex.hpp>
+ #include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
+ #include <boost/foreach.hpp>
  
  using namespace std;
  using namespace boost;
@@@ -271,7 -278,7 +278,7 @@@ string strprintf(const char* format, ..
          if (ret >= 0 && ret < limit)
              break;
          if (p != buffer)
 -            delete p;
 +            delete[] p;
          limit *= 2;
          p = new char[limit];
          if (p == NULL)
      }
      string str(p, p+ret);
      if (p != buffer)
 -        delete p;
 +        delete[] p;
      return str;
  }
  
@@@ -895,10 -902,8 +902,10 @@@ string FormatVersion(int nVersion
  string FormatFullVersion()
  {
      string s = FormatVersion(VERSION) + pszSubVer;
 -    if (VERSION_IS_BETA)
 -        s += _("-beta");
 +    if (VERSION_IS_BETA) {
 +        s += "-";
 +        s += _("beta");
 +    }
      return s;
  }
  
diff --combined src/util.h
@@@ -15,7 -15,6 +15,6 @@@
  #include <vector>
  #include <string>
  
- #include <boost/foreach.hpp>
  #include <boost/thread.hpp>
  #include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
  #include <boost/date_time/gregorian/gregorian_types.hpp>
@@@ -105,8 -104,6 +104,8 @@@ T* alignup(T* p
  typedef int socklen_t;
  #else
  #define WSAGetLastError()   errno
 +#define WSAEINVAL           EINVAL
 +#define WSAEALREADY         EALREADY
  #define WSAEWOULDBLOCK      EWOULDBLOCK
  #define WSAEMSGSIZE         EMSGSIZE
  #define WSAEINTR            EINTR