From 2f8f51d1e4e5285fdd5724f7264d32d08a42f7e9 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Thu, 11 Aug 2011 11:21:55 +0200 Subject: [PATCH 01/29] Missed a 'password' should be 'passphrase'. --- doc/README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/README b/doc/README index f72bca01f..5a05950b9 100644 --- a/doc/README +++ b/doc/README @@ -36,7 +36,7 @@ every time you wish to send Bitcoins. If you lose this passphrase, you will lose access to spend all of the bitcoins in your wallet, no one, not even the Bitcoin developers can recover your Bitcoins. This means you are responsible for your own security, store your -password in a secure location and do not forget it. +passphrase in a secure location and do not forget it. Remember that the encryption built into bitcoin only encrypts the actual keys which are required to send your bitcoins, not the full From 8acb491eef2044443b34e867b91ddb70244cefcf Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Thu, 11 Aug 2011 13:18:37 +0200 Subject: [PATCH 02/29] Fix incorrect RPC error messages --- src/rpc.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rpc.cpp b/src/rpc.cpp index d62a0d9ac..dd3430d42 100644 --- a/src/rpc.cpp +++ b/src/rpc.cpp @@ -552,7 +552,7 @@ Value sendtoaddress(const Array& params, bool fHelp) CRITICAL_BLOCK(pwalletMain->cs_vMasterKey) { if(pwalletMain->IsLocked()) - throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect."); + throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first."); string strError = pwalletMain->SendMoneyToBitcoinAddress(address, nAmount, wtx); if (strError != "") @@ -827,7 +827,7 @@ Value sendfrom(const Array& params, bool fHelp) CRITICAL_BLOCK(pwalletMain->cs_vMasterKey) { if(pwalletMain->IsLocked()) - throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect."); + throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first."); // Check funds int64 nBalance = GetAccountBalance(strAccount, nMinDepth); @@ -894,7 +894,7 @@ Value sendmany(const Array& params, bool fHelp) CRITICAL_BLOCK(pwalletMain->cs_vMasterKey) { if(pwalletMain->IsLocked()) - throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect."); + throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first."); // Check funds int64 nBalance = GetAccountBalance(strAccount, nMinDepth); From 59ed5cb398f3817cebd8f5c6aeba3424de2acefe Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Thu, 11 Aug 2011 13:09:25 +0200 Subject: [PATCH 03/29] Add specific wallet encryption details to doc/README --- doc/README | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/doc/README b/doc/README index 5a05950b9..831d66069 100644 --- a/doc/README +++ b/doc/README @@ -67,6 +67,50 @@ entering your wallet passphrase in the Bitcoin client and using the same passphrase only as your wallet passphrase. +Technical details of wallet encryption +-------------------------------------- +Wallet encryption uses AES-256-CBC to encrypt only the private keys +that are held in a wallet. The keys are encrypted with a master key +which is entirely random. This master key is then encrypted with +AES-256-CBC with a key derived from the passphrase using SHA512 and +OpenSSL's EVP_BytesToKey and a dynamic number of rounds determined by +the speed of the machine which does the initial encryption (and is +updated based on the speed of a computer which does a subsequent +passphrase change). Although the underlying code supports multiple +encrypted copies of the same master key (and thus multiple passphrases) +the client does not yet have a method to add additional passphrases. + +At runtime, the client loads the wallet as it normally would, however +the keystore stores the keys in encrypted form. When the passphrase +is required (to top up keypool or send coins) it will either be queried +by a GUI prompt, or must first be entered with the walletpassphrase +RPC command. This will change the wallet to "unlocked" state where the +unencrypted master key is stored in memory (in the case of GUI, only for +long enough to complete the requested operation, in RPC, for as long as +is specified by the second parameter to walletpassphrase). The wallet is +then locked (or can be manually locked using the walletlock RPC command) +and the unencrypted master key is removed from memory. + +Implementation details of wallet encryption +------------------------------------------- +When the wallet is locked, calls to sendtoaddress, sendfrom, sendmany, +and keypoolrefill will return Error -13: "Error: Please enter the wallet +passphrase with walletpassphrase first." + +When the wallet is unlocked, calls to walletpassphrase will fail. + +When a wallet is encrypted, the passphrase is required to top up the +keypool, thus, if the passphrase is rarely entered, it is possible that +keypool might run out. In this case, the default key will be used as the +target for payouts for mining, and calls to getnewaddress and getaccount +address will return an error. In order to prevent such cases, the keypool +is automatically refilled when walletpassphrase is called with a correct +passphrase and when topupkeypool is called (while the wallet is unlocked). +Note that the keypool continues to be topped up on various occasions when +a new key from pool is used and the wallet is unlocked (or unencrypted). + + + See the documentation at the bitcoin wiki: https://en.bitcoin.it/wiki/Main_Page From d0d9486f44a7872406530ef77f65da9ec3e78a94 Mon Sep 17 00:00:00 2001 From: "Fabian H jr." Date: Mon, 15 Aug 2011 21:33:00 -0300 Subject: [PATCH 04/29] Updated checkpoints, maybe Tx fee should be reduced to 0.0001 from 0.0005 and maximum minimum tx should be 0.0010. --- src/main.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index ee9165095..70b9ce559 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -30,7 +30,7 @@ map mapNextTx; map mapBlockIndex; uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"); CBigNum bnProofOfWorkLimit(~uint256(0) >> 32); -const int nTotalBlocksEstimate = 134444; // Conservative estimate of total nr of blocks on main chain +const int nTotalBlocksEstimate = 140700; // Conservative estimate of total nr of blocks on main chain const int nInitialBlockThreshold = 120; // Regard blocks up until N-threshold as "initial download" CBlockIndex* pindexGenesisBlock = NULL; int nBestHeight = -1; @@ -295,9 +295,10 @@ int CMerkleTx::SetMerkleBranch(const CBlock* pblock) bool CTransaction::CheckTransaction() const { // Basic checks that don't depend on any context - if (vin.empty() || vout.empty()) - return error("CTransaction::CheckTransaction() : vin or vout empty"); - + if (vin.empty()) + return error("CTransaction::CheckTransaction() : vin empty"); + if (vout.empty()) + return error("CTransaction::CheckTransaction() : vout empty"); // Size limits if (::GetSerializeSize(*this, SER_NETWORK) > MAX_BLOCK_SIZE) return error("CTransaction::CheckTransaction() : size limits failed"); @@ -1301,7 +1302,8 @@ bool CBlock::AcceptBlock() (nHeight == 74000 && hash != uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")) || (nHeight == 105000 && hash != uint256("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97")) || (nHeight == 118000 && hash != uint256("0x000000000000774a7f8a7a12dc906ddb9e17e75d684f15e00f8767f9e8f36553")) || - (nHeight == 134444 && hash != uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"))) + (nHeight == 134444 && hash != uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe")) || + (nHeight == 140700 && hash != uint256("0x000000000000033b512028abb90e1626d8b346fd0ed598ac0a3c371138dce2bd"))) return error("AcceptBlock() : rejected by checkpoint lockin at %d", nHeight); // Write block to history file @@ -1318,7 +1320,7 @@ bool CBlock::AcceptBlock() if (hashBestChain == hash) CRITICAL_BLOCK(cs_vNodes) BOOST_FOREACH(CNode* pnode, vNodes) - if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : 134444)) + if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : 140700)) pnode->PushInventory(CInv(MSG_BLOCK, hash)); return true; @@ -2664,7 +2666,7 @@ unsigned int static ScanHash_CryptoPP(char* pmidstate, char* pdata, char* phash1 } } - +// Some explaining would be appreciated class COrphan { public: From 99860de3c9b5809110538e1ab2d4e216d77b5aaf Mon Sep 17 00:00:00 2001 From: Giel van Schijndel Date: Thu, 11 Aug 2011 13:41:01 +0200 Subject: [PATCH 05/29] Make some global variables less-global (static) Explicitly make these global variables less-global to reduce the maximum scope of this global state. In my experience global variables tend to be a major source of bugs. As such the less accessible they are the less likely they are to be the source of a bug. Signed-off-by: Giel van Schijndel --- src/main.cpp | 4 ++-- src/main.h | 13 ------------- src/net.cpp | 4 ++-- src/net.h | 2 -- 4 files changed, 4 insertions(+), 19 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index f48331206..8b4b3df98 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -22,14 +22,14 @@ set setpwalletRegistered; CCriticalSection cs_main; -map mapTransactions; +static map mapTransactions; CCriticalSection cs_mapTransactions; unsigned int nTransactionsUpdated = 0; map mapNextTx; map mapBlockIndex; uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"); -CBigNum bnProofOfWorkLimit(~uint256(0) >> 32); +static CBigNum bnProofOfWorkLimit(~uint256(0) >> 32); const int nTotalBlocksEstimate = 134444; // Conservative estimate of total nr of blocks on main chain const int nInitialBlockThreshold = 120; // Regard blocks up until N-threshold as "initial download" CBlockIndex* pindexGenesisBlock = NULL; diff --git a/src/main.h b/src/main.h index 97a40d3ec..d4b89225d 100644 --- a/src/main.h +++ b/src/main.h @@ -54,7 +54,6 @@ static const int fHaveUPnP = false; extern CCriticalSection cs_main; extern std::map mapBlockIndex; extern uint256 hashGenesisBlock; -extern CBigNum bnProofOfWorkLimit; extern CBlockIndex* pindexGenesisBlock; extern int nBestHeight; extern CBigNum bnBestChainWork; @@ -1558,16 +1557,4 @@ public: bool ProcessAlert(); }; - - - - - - - - - - -extern std::map mapTransactions; - #endif diff --git a/src/net.cpp b/src/net.cpp index 3953f021e..df98457c7 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -50,10 +50,10 @@ bool fClient = false; bool fAllowDNS = false; uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK); CAddress addrLocalHost("0.0.0.0", 0, false, nLocalServices); -CNode* pnodeLocalHost = NULL; +static CNode* pnodeLocalHost = NULL; uint64 nLocalHostNonce = 0; array vnThreadsRunning; -SOCKET hListenSocket = INVALID_SOCKET; +static SOCKET hListenSocket = INVALID_SOCKET; vector vNodes; CCriticalSection cs_vNodes; diff --git a/src/net.h b/src/net.h index 3b098e1a8..52568ef4c 100644 --- a/src/net.h +++ b/src/net.h @@ -476,10 +476,8 @@ extern bool fClient; extern bool fAllowDNS; extern uint64 nLocalServices; extern CAddress addrLocalHost; -extern CNode* pnodeLocalHost; extern uint64 nLocalHostNonce; extern boost::array vnThreadsRunning; -extern SOCKET hListenSocket; extern std::vector vNodes; extern CCriticalSection cs_vNodes; From e49b83bb1242b37717e5cfabc344b0ff7157484e Mon Sep 17 00:00:00 2001 From: Giel van Schijndel Date: Thu, 11 Aug 2011 17:19:36 +0200 Subject: [PATCH 06/29] Cleanup makefiles such that diffs to them are smaller Signed-off-by: Giel van Schijndel --- src/makefile.linux-mingw | 37 +++++++++++++++++++++++-------- src/makefile.mingw | 37 +++++++++++++++++++++++-------- src/makefile.osx | 37 +++++++++++++++++++++++-------- src/makefile.unix | 37 +++++++++++++++++++++++-------- src/makefile.vc | 48 +++++++++++++++++++++++++++++----------- 5 files changed, 147 insertions(+), 49 deletions(-) diff --git a/src/makefile.linux-mingw b/src/makefile.linux-mingw index e2ef4213a..c03cb9d2a 100644 --- a/src/makefile.linux-mingw +++ b/src/makefile.linux-mingw @@ -35,9 +35,28 @@ LIBS= \ DEFS=-D_MT -DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH -DUSE_SSL DEBUGFLAGS=-g -D__WXDEBUG__ CFLAGS=-O2 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) -HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \ - script.h db.h net.h irc.h keystore.h main.h wallet.h rpc.h uibase.h ui.h noui.h \ - crypter.h init.h +HEADERS = \ + base58.h \ + bignum.h \ + crypter.h \ + db.h \ + headers.h \ + init.h \ + irc.h \ + key.h \ + keystore.h \ + main.h \ + net.h \ + noui.h \ + rpc.h \ + script.h \ + serialize.h \ + strlcpy.h \ + ui.h \ + uibase.h \ + uint256.h \ + util.h \ + wallet.h ifdef USE_UPNP INCLUDEPATHS += -I"$(DEPSDIR)/upnpc-exe-win32-20110215" @@ -49,17 +68,17 @@ endif LIBS += -l mingwthrd -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l shlwapi OBJS= \ - obj/util.o \ - obj/script.o \ + obj/crypter.o \ obj/db.o \ - obj/net.o \ + obj/init.o \ obj/irc.o \ obj/keystore.o \ obj/main.o \ - obj/wallet.o \ + obj/net.o \ obj/rpc.o \ - obj/init.o \ - obj/crypter.o \ + obj/script.o \ + obj/util.o \ + obj/wallet.o \ cryptopp/obj/sha.o \ cryptopp/obj/cpu.o diff --git a/src/makefile.mingw b/src/makefile.mingw index 96f81b306..55cb8a705 100644 --- a/src/makefile.mingw +++ b/src/makefile.mingw @@ -32,9 +32,28 @@ LIBS= \ DEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH -DUSE_SSL DEBUGFLAGS=-g -D__WXDEBUG__ CFLAGS=-mthreads -O2 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) -HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \ - script.h db.h net.h irc.h keystore.h main.h wallet.h rpc.h uibase.h ui.h noui.h \ - init.h crypter.h +HEADERS = \ + base58.h \ + bignum.h \ + crypter.h \ + db.h \ + headers.h \ + init.h \ + irc.h \ + key.h \ + keystore.h \ + main.h \ + net.h \ + noui.h \ + rpc.h \ + script.h \ + serialize.h \ + strlcpy.h \ + ui.h \ + uibase.h \ + uint256.h \ + util.h \ + wallet.h ifdef USE_UPNP INCLUDEPATHS += -I"C:\upnpc-exe-win32-20110215" @@ -46,17 +65,17 @@ endif LIBS += -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l shlwapi OBJS= \ - obj/util.o \ - obj/script.o \ + obj/crypter.o \ obj/db.o \ - obj/net.o \ + obj/init.o \ obj/irc.o \ obj/keystore.o \ obj/main.o \ - obj/wallet.o \ + obj/net.o \ obj/rpc.o \ - obj/init.o \ - obj/crypter.o \ + obj/script.o \ + obj/util.o \ + obj/wallet.o \ cryptopp/obj/sha.o \ cryptopp/obj/cpu.o diff --git a/src/makefile.osx b/src/makefile.osx index 699911d4e..7172bcc41 100644 --- a/src/makefile.osx +++ b/src/makefile.osx @@ -32,22 +32,41 @@ DEFS=$(shell $(DEPSDIR)/bin/wx-config --cxxflags) -D__WXMAC_OSX__ -DNOPCH -DMSG_ DEBUGFLAGS=-g -DwxDEBUG_LEVEL=0 # ppc doesn't work because we don't support big-endian CFLAGS=-mmacosx-version-min=10.5 -arch i386 -arch x86_64 -O3 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) -HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \ - script.h db.h net.h irc.h keystore.h main.h wallet.h rpc.h uibase.h ui.h noui.h \ - init.h crypter.h +HEADERS = \ + base58.h \ + bignum.h \ + crypter.h \ + db.h \ + headers.h \ + init.h \ + irc.h \ + key.h \ + keystore.h \ + main.h \ + net.h \ + noui.h \ + rpc.h \ + script.h \ + serialize.h \ + strlcpy.h \ + ui.h \ + uibase.h \ + uint256.h \ + util.h \ + wallet.h OBJS= \ - obj/util.o \ - obj/script.o \ + obj/crypter.o \ obj/db.o \ - obj/net.o \ + obj/init.o \ obj/irc.o \ obj/keystore.o \ obj/main.o \ - obj/wallet.o \ + obj/net.o \ obj/rpc.o \ - obj/init.o \ - obj/crypter.o \ + obj/script.o \ + obj/util.o \ + obj/wallet.o \ cryptopp/obj/sha.o \ cryptopp/obj/cpu.o diff --git a/src/makefile.unix b/src/makefile.unix index 4c9279729..7cc72e0ea 100644 --- a/src/makefile.unix +++ b/src/makefile.unix @@ -38,22 +38,41 @@ LIBS+= \ DEBUGFLAGS=-g -D__WXDEBUG__ CXXFLAGS=-O2 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) -HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \ - script.h db.h net.h irc.h keystore.h main.h wallet.h rpc.h uibase.h ui.h noui.h \ - init.h crypter.h +HEADERS = \ + base58.h \ + bignum.h \ + crypter.h \ + db.h \ + headers.h \ + init.h \ + irc.h \ + key.h \ + keystore.h \ + main.h \ + net.h \ + noui.h \ + rpc.h \ + script.h \ + serialize.h \ + strlcpy.h \ + ui.h \ + uibase.h \ + uint256.h \ + util.h \ + wallet.h OBJS= \ - obj/util.o \ - obj/script.o \ + obj/crypter.o \ obj/db.o \ - obj/net.o \ + obj/init.o \ obj/irc.o \ obj/keystore.o \ obj/main.o \ - obj/wallet.o \ + obj/net.o \ obj/rpc.o \ - obj/init.o \ - obj/crypter.o \ + obj/script.o \ + obj/util.o \ + obj/wallet.o \ cryptopp/obj/sha.o \ cryptopp/obj/cpu.o diff --git a/src/makefile.vc b/src/makefile.vc index c050deb6e..edaba80a7 100644 --- a/src/makefile.vc +++ b/src/makefile.vc @@ -45,21 +45,43 @@ LIBS=$(LIBS) \ DEBUGFLAGS=/Os CFLAGS=/MD /c /nologo /EHsc /GR /Zm300 $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) -HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \ - script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h noui.h init.h wallet.h keystore.h crypter.h +HEADERS = \ + base58.h \ + bignum.h \ + crypter.h \ + db.h \ + headers.h \ + init.h \ + irc.h \ + key.h \ + keystore.h \ + main.h \ + net.h \ + noui.h \ + rpc.h \ + script.h \ + serialize.h \ + strlcpy.h \ + ui.h \ + uibase.h \ + uint256.h \ + util.h \ + wallet.h OBJS= \ - obj\util.obj \ - obj\script.obj \ - obj\db.obj \ - obj\net.obj \ - obj\irc.obj \ - obj\keystore.obj \ - obj\main.obj \ - obj\wallet.obj \ - obj\rpc.obj \ - obj\init.obj \ - obj\crypter.obj + obj\crypter.o \ + obj\db.o \ + obj\init.o \ + obj\irc.o \ + obj\keystore.o \ + obj\main.o \ + obj\net.o \ + obj\rpc.o \ + obj\script.o \ + obj\util.o \ + obj\wallet.o \ + cryptopp\obj\sha.o \ + cryptopp\obj\cpu.o CRYPTOPP_OBJS= \ cryptopp\obj\sha.obj \ From 82dc6426b4cbf769ace7976c2a40d160b8d76f08 Mon Sep 17 00:00:00 2001 From: Giel van Schijndel Date: Thu, 11 Aug 2011 18:12:14 +0200 Subject: [PATCH 07/29] Move func 'REF' from util.h to serialize.h util.h doesn't use REF, serialize.h does, creating a dependency of serialize.h on util.h, but util.h already depends on serialize.h. To resolve this circular dependency the function 'REF' has now been moved closer to one of its two points of use. Signed-off-by: Giel van Schijndel --- src/serialize.h | 11 +++++++---- src/util.h | 8 -------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/serialize.h b/src/serialize.h index c55775242..0a31ff557 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -63,10 +63,13 @@ static const int VERSION = 32500; static const char* pszSubVer = ""; static const bool VERSION_IS_BETA = true; - - - - +// Used to bypass the rule against non-const reference to temporary +// where it makes sense with wrappers such as CFlatData or CTxDB +template +inline T& REF(const T& val) +{ + return const_cast(val); +} ///////////////////////////////////////////////////////////////// // diff --git a/src/util.h b/src/util.h index 1e4ceb246..3d7ef108b 100644 --- a/src/util.h +++ b/src/util.h @@ -67,14 +67,6 @@ typedef unsigned long long uint64; // This is needed because the foreach macro can't get over the comma in pair #define PAIRTYPE(t1, t2) pair -// Used to bypass the rule against non-const reference to temporary -// where it makes sense with wrappers such as CFlatData or CTxDB -template -inline T& REF(const T& val) -{ - return (T&)val; -} - // Align by increasing pointer, must have extra space at end of buffer template T* alignup(T* p) From 507fd9d15baac950df494742d67bcbafdaa4752c Mon Sep 17 00:00:00 2001 From: Giel van Schijndel Date: Thu, 11 Aug 2011 18:14:53 +0200 Subject: [PATCH 08/29] Start moving protocol-specific code to protocol.[ch]pp Move CMessageHeader from net.h to protocol.[ch]pp, with the implementation in the .cpp compilation unit (compiling once is enough). This commit does *not* and should not modify *any* code, it only moves it from net.h and splits it across protocol.cpp and protocol.hpp. Indentation changes aside the closest thing to a modification of code is the addition of the 'TODO' comment (the execution of which requires code modifications and thus doesn't belong in this commit). Signed-off-by: Giel van Schijndel --- src/main.h | 1 - src/makefile.linux-mingw | 2 + src/makefile.mingw | 2 + src/makefile.osx | 2 + src/makefile.unix | 2 + src/makefile.vc | 2 + src/net.h | 98 +--------------------------------------- src/protocol.cpp | 61 +++++++++++++++++++++++++ src/protocol.h | 52 +++++++++++++++++++++ 9 files changed, 125 insertions(+), 97 deletions(-) create mode 100644 src/protocol.cpp create mode 100644 src/protocol.h diff --git a/src/main.h b/src/main.h index d4b89225d..427067bc9 100644 --- a/src/main.h +++ b/src/main.h @@ -21,7 +21,6 @@ class CKeyItem; class CReserveKey; class CWalletDB; -class CMessageHeader; class CAddress; class CInv; class CRequestTracker; diff --git a/src/makefile.linux-mingw b/src/makefile.linux-mingw index c03cb9d2a..12f6e212f 100644 --- a/src/makefile.linux-mingw +++ b/src/makefile.linux-mingw @@ -48,6 +48,7 @@ HEADERS = \ main.h \ net.h \ noui.h \ + protocol.h \ rpc.h \ script.h \ serialize.h \ @@ -75,6 +76,7 @@ OBJS= \ obj/keystore.o \ obj/main.o \ obj/net.o \ + obj/protocol.o \ obj/rpc.o \ obj/script.o \ obj/util.o \ diff --git a/src/makefile.mingw b/src/makefile.mingw index 55cb8a705..893700b88 100644 --- a/src/makefile.mingw +++ b/src/makefile.mingw @@ -45,6 +45,7 @@ HEADERS = \ main.h \ net.h \ noui.h \ + protocol.h \ rpc.h \ script.h \ serialize.h \ @@ -72,6 +73,7 @@ OBJS= \ obj/keystore.o \ obj/main.o \ obj/net.o \ + obj/protocol.o \ obj/rpc.o \ obj/script.o \ obj/util.o \ diff --git a/src/makefile.osx b/src/makefile.osx index 7172bcc41..48908d9f3 100644 --- a/src/makefile.osx +++ b/src/makefile.osx @@ -45,6 +45,7 @@ HEADERS = \ main.h \ net.h \ noui.h \ + protocol.h \ rpc.h \ script.h \ serialize.h \ @@ -63,6 +64,7 @@ OBJS= \ obj/keystore.o \ obj/main.o \ obj/net.o \ + obj/protocol.o \ obj/rpc.o \ obj/script.o \ obj/util.o \ diff --git a/src/makefile.unix b/src/makefile.unix index 7cc72e0ea..a4f13ae2c 100644 --- a/src/makefile.unix +++ b/src/makefile.unix @@ -51,6 +51,7 @@ HEADERS = \ main.h \ net.h \ noui.h \ + protocol.h \ rpc.h \ script.h \ serialize.h \ @@ -69,6 +70,7 @@ OBJS= \ obj/keystore.o \ obj/main.o \ obj/net.o \ + obj/protocol.o \ obj/rpc.o \ obj/script.o \ obj/util.o \ diff --git a/src/makefile.vc b/src/makefile.vc index edaba80a7..a5437bcf5 100644 --- a/src/makefile.vc +++ b/src/makefile.vc @@ -58,6 +58,7 @@ HEADERS = \ main.h \ net.h \ noui.h \ + protocol.h \ rpc.h \ script.h \ serialize.h \ @@ -77,6 +78,7 @@ OBJS= \ obj\main.o \ obj\net.o \ obj\rpc.o \ + obj\protocol.o \ obj\script.o \ obj\util.o \ obj\wallet.o \ diff --git a/src/net.h b/src/net.h index 52568ef4c..7a4706d53 100644 --- a/src/net.h +++ b/src/net.h @@ -14,7 +14,8 @@ #include #endif -class CMessageHeader; +#include "protocol.h" + class CAddress; class CAddrDB; class CInv; @@ -54,101 +55,6 @@ bool BindListenPort(std::string& strError=REF(std::string())); void StartNode(void* parg); bool StopNode(); - - - - - - - -// -// Message header -// (4) message start -// (12) command -// (4) size -// (4) checksum - -extern unsigned char pchMessageStart[4]; - -class CMessageHeader -{ -public: - enum { COMMAND_SIZE=12 }; - char pchMessageStart[sizeof(::pchMessageStart)]; - char pchCommand[COMMAND_SIZE]; - unsigned int nMessageSize; - unsigned int nChecksum; - - CMessageHeader() - { - memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)); - memset(pchCommand, 0, sizeof(pchCommand)); - pchCommand[1] = 1; - nMessageSize = -1; - nChecksum = 0; - } - - CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn) - { - memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)); - strncpy(pchCommand, pszCommand, COMMAND_SIZE); - nMessageSize = nMessageSizeIn; - nChecksum = 0; - } - - IMPLEMENT_SERIALIZE - ( - READWRITE(FLATDATA(pchMessageStart)); - READWRITE(FLATDATA(pchCommand)); - READWRITE(nMessageSize); - if (nVersion >= 209) - READWRITE(nChecksum); - ) - - std::string GetCommand() - { - if (pchCommand[COMMAND_SIZE-1] == 0) - return std::string(pchCommand, pchCommand + strlen(pchCommand)); - else - return std::string(pchCommand, pchCommand + COMMAND_SIZE); - } - - bool IsValid() - { - // Check start string - if (memcmp(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)) != 0) - return false; - - // Check the command string for errors - for (char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; p1++) - { - if (*p1 == 0) - { - // Must be all zeros after the first zero - for (; p1 < pchCommand + COMMAND_SIZE; p1++) - if (*p1 != 0) - return false; - } - else if (*p1 < ' ' || *p1 > 0x7E) - return false; - } - - // Message size - if (nMessageSize > MAX_SIZE) - { - printf("CMessageHeader::IsValid() : (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand().c_str(), nMessageSize); - return false; - } - - return true; - } -}; - - - - - - static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; class CAddress diff --git a/src/protocol.cpp b/src/protocol.cpp new file mode 100644 index 000000000..0bb1da93e --- /dev/null +++ b/src/protocol.cpp @@ -0,0 +1,61 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +#include "protocol.h" + +CMessageHeader::CMessageHeader() +{ + memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)); + memset(pchCommand, 0, sizeof(pchCommand)); + pchCommand[1] = 1; + nMessageSize = -1; + nChecksum = 0; +} + +CMessageHeader::CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn) +{ + memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)); + strncpy(pchCommand, pszCommand, COMMAND_SIZE); + nMessageSize = nMessageSizeIn; + nChecksum = 0; +} + +std::string CMessageHeader::GetCommand() const +{ + if (pchCommand[COMMAND_SIZE-1] == 0) + return std::string(pchCommand, pchCommand + strlen(pchCommand)); + else + return std::string(pchCommand, pchCommand + COMMAND_SIZE); +} + +bool CMessageHeader::IsValid() const +{ + // Check start string + if (memcmp(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)) != 0) + return false; + + // Check the command string for errors + for (const char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; p1++) + { + if (*p1 == 0) + { + // Must be all zeros after the first zero + for (; p1 < pchCommand + COMMAND_SIZE; p1++) + if (*p1 != 0) + return false; + } + else if (*p1 < ' ' || *p1 > 0x7E) + return false; + } + + // Message size + if (nMessageSize > MAX_SIZE) + { + printf("CMessageHeader::IsValid() : (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand().c_str(), nMessageSize); + return false; + } + + return true; +} diff --git a/src/protocol.h b/src/protocol.h new file mode 100644 index 000000000..b5baeb2a6 --- /dev/null +++ b/src/protocol.h @@ -0,0 +1,52 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +#ifndef __cplusplus +# error This header can only be compiled as C++. +#endif + +#ifndef __INCLUDED_PROTOCOL_H__ +#define __INCLUDED_PROTOCOL_H__ + +#include "serialize.h" +#include + +// +// Message header +// (4) message start +// (12) command +// (4) size +// (4) checksum + +extern unsigned char pchMessageStart[4]; + +class CMessageHeader +{ + public: + CMessageHeader(); + CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn); + + std::string GetCommand() const; + bool IsValid() const; + + IMPLEMENT_SERIALIZE + ( + READWRITE(FLATDATA(pchMessageStart)); + READWRITE(FLATDATA(pchCommand)); + READWRITE(nMessageSize); + if (nVersion >= 209) + READWRITE(nChecksum); + ) + + // TODO: make private (improves encapsulation) + public: + enum { COMMAND_SIZE=12 }; + char pchMessageStart[sizeof(::pchMessageStart)]; + char pchCommand[COMMAND_SIZE]; + unsigned int nMessageSize; + unsigned int nChecksum; +}; + +#endif // __INCLUDED_PROTOCOL_H__ From 33e28c9948336784324cf5c7248ce608b93dbfde Mon Sep 17 00:00:00 2001 From: Giel van Schijndel Date: Thu, 11 Aug 2011 18:40:12 +0200 Subject: [PATCH 09/29] Move CAddress to protocol.[ch]pp This commit does *not* and should not modify *any* code, it only moves it from net.h and splits it across protocol.cpp and protocol.hpp. Signed-off-by: Giel van Schijndel --- src/net.h | 225 ----------------------------------------------- src/protocol.cpp | 190 +++++++++++++++++++++++++++++++++++++++ src/protocol.h | 71 +++++++++++++++ 3 files changed, 261 insertions(+), 225 deletions(-) diff --git a/src/net.h b/src/net.h index 7a4706d53..66f3949b8 100644 --- a/src/net.h +++ b/src/net.h @@ -16,7 +16,6 @@ #include "protocol.h" -class CAddress; class CAddrDB; class CInv; class CRequestTracker; @@ -29,15 +28,7 @@ extern int nConnectTimeout; inline unsigned int ReceiveBufferSize() { return 1000*GetArg("-maxreceivebuffer", 10*1000); } inline unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 10*1000); } -inline unsigned short GetDefaultPort() { return fTestNet ? 18333 : 8333; } static const unsigned int PUBLISH_HOPS = 5; -enum -{ - NODE_NETWORK = (1 << 0), -}; - - - bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout=nConnectTimeout); bool Lookup(const char *pszName, std::vector& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false); @@ -55,222 +46,6 @@ bool BindListenPort(std::string& strError=REF(std::string())); void StartNode(void* parg); bool StopNode(); -static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; - -class CAddress -{ -public: - uint64 nServices; - unsigned char pchReserved[12]; - unsigned int ip; - unsigned short port; - - // disk and network only - unsigned int nTime; - - // memory only - unsigned int nLastTry; - - CAddress() - { - Init(); - } - - CAddress(unsigned int ipIn, unsigned short portIn=0, uint64 nServicesIn=NODE_NETWORK) - { - Init(); - ip = ipIn; - port = htons(portIn == 0 ? GetDefaultPort() : portIn); - nServices = nServicesIn; - } - - explicit CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn=NODE_NETWORK) - { - Init(); - ip = sockaddr.sin_addr.s_addr; - port = sockaddr.sin_port; - nServices = nServicesIn; - } - - explicit CAddress(const char* pszIn, int portIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK) - { - Init(); - Lookup(pszIn, *this, nServicesIn, fNameLookup, portIn); - } - - explicit CAddress(const char* pszIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK) - { - Init(); - Lookup(pszIn, *this, nServicesIn, fNameLookup, 0, true); - } - - explicit CAddress(std::string strIn, int portIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK) - { - Init(); - Lookup(strIn.c_str(), *this, nServicesIn, fNameLookup, portIn); - } - - explicit CAddress(std::string strIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK) - { - Init(); - Lookup(strIn.c_str(), *this, nServicesIn, fNameLookup, 0, true); - } - - void Init() - { - nServices = NODE_NETWORK; - memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); - ip = INADDR_NONE; - port = htons(GetDefaultPort()); - nTime = 100000000; - nLastTry = 0; - } - - IMPLEMENT_SERIALIZE - ( - if (fRead) - const_cast(this)->Init(); - if (nType & SER_DISK) - READWRITE(nVersion); - if ((nType & SER_DISK) || (nVersion >= 31402 && !(nType & SER_GETHASH))) - READWRITE(nTime); - READWRITE(nServices); - READWRITE(FLATDATA(pchReserved)); // for IPv6 - READWRITE(ip); - READWRITE(port); - ) - - friend inline bool operator==(const CAddress& a, const CAddress& b) - { - return (memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved)) == 0 && - a.ip == b.ip && - a.port == b.port); - } - - friend inline bool operator!=(const CAddress& a, const CAddress& b) - { - return (!(a == b)); - } - - friend inline bool operator<(const CAddress& a, const CAddress& b) - { - int ret = memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved)); - if (ret < 0) - return true; - else if (ret == 0) - { - if (ntohl(a.ip) < ntohl(b.ip)) - return true; - else if (a.ip == b.ip) - return ntohs(a.port) < ntohs(b.port); - } - return false; - } - - std::vector GetKey() const - { - CDataStream ss; - ss.reserve(18); - ss << FLATDATA(pchReserved) << ip << port; - - #if defined(_MSC_VER) && _MSC_VER < 1300 - return std::vector((unsigned char*)&ss.begin()[0], (unsigned char*)&ss.end()[0]); - #else - return std::vector(ss.begin(), ss.end()); - #endif - } - - struct sockaddr_in GetSockAddr() const - { - struct sockaddr_in sockaddr; - memset(&sockaddr, 0, sizeof(sockaddr)); - sockaddr.sin_family = AF_INET; - sockaddr.sin_addr.s_addr = ip; - sockaddr.sin_port = port; - return sockaddr; - } - - bool IsIPv4() const - { - return (memcmp(pchReserved, pchIPv4, sizeof(pchIPv4)) == 0); - } - - bool IsRFC1918() const - { - return IsIPv4() && (GetByte(3) == 10 || - (GetByte(3) == 192 && GetByte(2) == 168) || - (GetByte(3) == 172 && - (GetByte(2) >= 16 && GetByte(2) <= 31))); - } - - bool IsRFC3927() const - { - return IsIPv4() && (GetByte(3) == 169 && GetByte(2) == 254); - } - - bool IsLocal() const - { - return IsIPv4() && (GetByte(3) == 127 || - GetByte(3) == 0); - } - - bool IsRoutable() const - { - return IsValid() && - !(IsRFC1918() || IsRFC3927() || IsLocal()); - } - - bool IsValid() const - { - // Clean up 3-byte shifted addresses caused by garbage in size field - // of addr messages from versions before 0.2.9 checksum. - // Two consecutive addr messages look like this: - // header20 vectorlen3 addr26 addr26 addr26 header20 vectorlen3 addr26 addr26 addr26... - // so if the first length field is garbled, it reads the second batch - // of addr misaligned by 3 bytes. - if (memcmp(pchReserved, pchIPv4+3, sizeof(pchIPv4)-3) == 0) - return false; - - return (ip != 0 && ip != INADDR_NONE && port != htons(USHRT_MAX)); - } - - unsigned char GetByte(int n) const - { - return ((unsigned char*)&ip)[3-n]; - } - - std::string ToStringIPPort() const - { - return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port)); - } - - std::string ToStringIP() const - { - return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0)); - } - - std::string ToStringPort() const - { - return strprintf("%u", ntohs(port)); - } - - std::string ToString() const - { - return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port)); - } - - void print() const - { - printf("CAddress(%s)\n", ToString().c_str()); - } -}; - - - - - - - enum { MSG_TX = 1, diff --git a/src/protocol.cpp b/src/protocol.cpp index 0bb1da93e..8d2dbfdd2 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -4,6 +4,17 @@ // file license.txt or http://www.opensource.org/licenses/mit-license.php. #include "protocol.h" +#include "util.h" + +#ifndef __WXMSW__ +# include +#endif + +// Prototypes from net.h, but that header (currently) stinks, can't #include it without breaking things +bool Lookup(const char *pszName, std::vector& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false); +bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false); + +static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; CMessageHeader::CMessageHeader() { @@ -59,3 +70,182 @@ bool CMessageHeader::IsValid() const return true; } + +CAddress::CAddress() +{ + Init(); +} + +CAddress::CAddress(unsigned int ipIn, unsigned short portIn, uint64 nServicesIn) +{ + Init(); + ip = ipIn; + port = htons(portIn == 0 ? GetDefaultPort() : portIn); + nServices = nServicesIn; +} + +CAddress::CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn) +{ + Init(); + ip = sockaddr.sin_addr.s_addr; + port = sockaddr.sin_port; + nServices = nServicesIn; +} + +CAddress::CAddress(const char* pszIn, int portIn, bool fNameLookup, uint64 nServicesIn) +{ + Init(); + Lookup(pszIn, *this, nServicesIn, fNameLookup, portIn); +} + +CAddress::CAddress(const char* pszIn, bool fNameLookup, uint64 nServicesIn) +{ + Init(); + Lookup(pszIn, *this, nServicesIn, fNameLookup, 0, true); +} + +CAddress::CAddress(std::string strIn, int portIn, bool fNameLookup, uint64 nServicesIn) +{ + Init(); + Lookup(strIn.c_str(), *this, nServicesIn, fNameLookup, portIn); +} + +CAddress::CAddress(std::string strIn, bool fNameLookup, uint64 nServicesIn) +{ + Init(); + Lookup(strIn.c_str(), *this, nServicesIn, fNameLookup, 0, true); +} + +void CAddress::Init() +{ + nServices = NODE_NETWORK; + memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); + ip = INADDR_NONE; + port = htons(GetDefaultPort()); + nTime = 100000000; + nLastTry = 0; +} + +bool operator==(const CAddress& a, const CAddress& b) +{ + return (memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved)) == 0 && + a.ip == b.ip && + a.port == b.port); +} + +bool operator!=(const CAddress& a, const CAddress& b) +{ + return (!(a == b)); +} + +bool operator<(const CAddress& a, const CAddress& b) +{ + int ret = memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved)); + if (ret < 0) + return true; + else if (ret == 0) + { + if (ntohl(a.ip) < ntohl(b.ip)) + return true; + else if (a.ip == b.ip) + return ntohs(a.port) < ntohs(b.port); + } + return false; +} + +std::vector CAddress::GetKey() const +{ + CDataStream ss; + ss.reserve(18); + ss << FLATDATA(pchReserved) << ip << port; + + #if defined(_MSC_VER) && _MSC_VER < 1300 + return std::vector((unsigned char*)&ss.begin()[0], (unsigned char*)&ss.end()[0]); + #else + return std::vector(ss.begin(), ss.end()); + #endif +} + +struct sockaddr_in CAddress::GetSockAddr() const +{ + struct sockaddr_in sockaddr; + memset(&sockaddr, 0, sizeof(sockaddr)); + sockaddr.sin_family = AF_INET; + sockaddr.sin_addr.s_addr = ip; + sockaddr.sin_port = port; + return sockaddr; +} + +bool CAddress::IsIPv4() const +{ + return (memcmp(pchReserved, pchIPv4, sizeof(pchIPv4)) == 0); +} + +bool CAddress::IsRFC1918() const +{ + return IsIPv4() && (GetByte(3) == 10 || + (GetByte(3) == 192 && GetByte(2) == 168) || + (GetByte(3) == 172 && + (GetByte(2) >= 16 && GetByte(2) <= 31))); +} + +bool CAddress::IsRFC3927() const +{ + return IsIPv4() && (GetByte(3) == 169 && GetByte(2) == 254); +} + +bool CAddress::IsLocal() const +{ + return IsIPv4() && (GetByte(3) == 127 || + GetByte(3) == 0); +} + +bool CAddress::IsRoutable() const +{ + return IsValid() && + !(IsRFC1918() || IsRFC3927() || IsLocal()); +} + +bool CAddress::IsValid() const +{ + // Clean up 3-byte shifted addresses caused by garbage in size field + // of addr messages from versions before 0.2.9 checksum. + // Two consecutive addr messages look like this: + // header20 vectorlen3 addr26 addr26 addr26 header20 vectorlen3 addr26 addr26 addr26... + // so if the first length field is garbled, it reads the second batch + // of addr misaligned by 3 bytes. + if (memcmp(pchReserved, pchIPv4+3, sizeof(pchIPv4)-3) == 0) + return false; + + return (ip != 0 && ip != INADDR_NONE && port != htons(USHRT_MAX)); +} + +unsigned char CAddress::GetByte(int n) const +{ + return ((unsigned char*)&ip)[3-n]; +} + +std::string CAddress::ToStringIPPort() const +{ + return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port)); +} + +std::string CAddress::ToStringIP() const +{ + return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0)); +} + +std::string CAddress::ToStringPort() const +{ + return strprintf("%u", ntohs(port)); +} + +std::string CAddress::ToString() const +{ + return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port)); +} + +void CAddress::print() const +{ + printf("CAddress(%s)\n", ToString().c_str()); +} diff --git a/src/protocol.h b/src/protocol.h index b5baeb2a6..009f67dfa 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -13,6 +13,12 @@ #include "serialize.h" #include +extern bool fTestNet; +static inline unsigned short GetDefaultPort(const bool testnet = fTestNet) +{ + return testnet ? 18333 : 8333; +} + // // Message header // (4) message start @@ -49,4 +55,69 @@ class CMessageHeader unsigned int nChecksum; }; +enum +{ + NODE_NETWORK = (1 << 0), +}; + +class CAddress +{ + public: + CAddress(); + CAddress(unsigned int ipIn, unsigned short portIn=0, uint64 nServicesIn=NODE_NETWORK); + explicit CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn=NODE_NETWORK); + explicit CAddress(const char* pszIn, int portIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK); + explicit CAddress(const char* pszIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK); + explicit CAddress(std::string strIn, int portIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK); + explicit CAddress(std::string strIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK); + + void Init(); + + IMPLEMENT_SERIALIZE + ( + if (fRead) + const_cast(this)->Init(); + if (nType & SER_DISK) + READWRITE(nVersion); + if ((nType & SER_DISK) || (nVersion >= 31402 && !(nType & SER_GETHASH))) + READWRITE(nTime); + READWRITE(nServices); + READWRITE(FLATDATA(pchReserved)); // for IPv6 + READWRITE(ip); + READWRITE(port); + ) + + friend bool operator==(const CAddress& a, const CAddress& b); + friend bool operator!=(const CAddress& a, const CAddress& b); + friend bool operator<(const CAddress& a, const CAddress& b); + + std::vector GetKey() const; + struct sockaddr_in GetSockAddr() const; + bool IsIPv4() const; + bool IsRFC1918() const; + bool IsRFC3927() const; + bool IsLocal() const; + bool IsRoutable() const; + bool IsValid() const; + unsigned char GetByte(int n) const; + std::string ToStringIPPort() const; + std::string ToStringIP() const; + std::string ToStringPort() const; + std::string ToString() const; + void print() const; + + // TODO: make private (improves encapsulation) + public: + uint64 nServices; + unsigned char pchReserved[12]; + unsigned int ip; + unsigned short port; + + // disk and network only + unsigned int nTime; + + // memory only + unsigned int nLastTry; +}; + #endif // __INCLUDED_PROTOCOL_H__ From e4dde849ae5544383703ef2d73592677e6c528ad Mon Sep 17 00:00:00 2001 From: Giel van Schijndel Date: Thu, 11 Aug 2011 18:49:03 +0200 Subject: [PATCH 10/29] Move CInv to protocol.[ch]pp This commit does *not* and should not modify *any* code, it only moves it from net.h and splits it across protocol.cpp and protocol.hpp. Signed-off-by: Giel van Schijndel --- src/net.h | 80 ------------------------------------------------ src/protocol.cpp | 61 ++++++++++++++++++++++++++++++++++++ src/protocol.h | 27 ++++++++++++++++ 3 files changed, 88 insertions(+), 80 deletions(-) diff --git a/src/net.h b/src/net.h index 66f3949b8..efac1f452 100644 --- a/src/net.h +++ b/src/net.h @@ -17,7 +17,6 @@ #include "protocol.h" class CAddrDB; -class CInv; class CRequestTracker; class CNode; class CBlockIndex; @@ -52,85 +51,6 @@ enum MSG_BLOCK, }; -static const char* ppszTypeName[] = -{ - "ERROR", - "tx", - "block", -}; - -class CInv -{ -public: - int type; - uint256 hash; - - CInv() - { - type = 0; - hash = 0; - } - - CInv(int typeIn, const uint256& hashIn) - { - type = typeIn; - hash = hashIn; - } - - CInv(const std::string& strType, const uint256& hashIn) - { - int i; - for (i = 1; i < ARRAYLEN(ppszTypeName); i++) - { - if (strType == ppszTypeName[i]) - { - type = i; - break; - } - } - if (i == ARRAYLEN(ppszTypeName)) - throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType.c_str())); - hash = hashIn; - } - - IMPLEMENT_SERIALIZE - ( - READWRITE(type); - READWRITE(hash); - ) - - friend inline bool operator<(const CInv& a, const CInv& b) - { - return (a.type < b.type || (a.type == b.type && a.hash < b.hash)); - } - - bool IsKnownType() const - { - return (type >= 1 && type < ARRAYLEN(ppszTypeName)); - } - - const char* GetCommand() const - { - if (!IsKnownType()) - throw std::out_of_range(strprintf("CInv::GetCommand() : type=%d unknown type", type)); - return ppszTypeName[type]; - } - - std::string ToString() const - { - return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,20).c_str()); - } - - void print() const - { - printf("CInv(%s)\n", ToString().c_str()); - } -}; - - - - - class CRequestTracker { public: diff --git a/src/protocol.cpp b/src/protocol.cpp index 8d2dbfdd2..48784b9cf 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -15,6 +15,12 @@ bool Lookup(const char *pszName, std::vector& vaddr, int nServices, in bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false); static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; +static const char* ppszTypeName[] = +{ + "ERROR", + "tx", + "block", +}; CMessageHeader::CMessageHeader() { @@ -249,3 +255,58 @@ void CAddress::print() const { printf("CAddress(%s)\n", ToString().c_str()); } + +CInv::CInv() +{ + type = 0; + hash = 0; +} + +CInv::CInv(int typeIn, const uint256& hashIn) +{ + type = typeIn; + hash = hashIn; +} + +CInv::CInv(const std::string& strType, const uint256& hashIn) +{ + int i; + for (i = 1; i < ARRAYLEN(ppszTypeName); i++) + { + if (strType == ppszTypeName[i]) + { + type = i; + break; + } + } + if (i == ARRAYLEN(ppszTypeName)) + throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType.c_str())); + hash = hashIn; +} + +bool operator<(const CInv& a, const CInv& b) +{ + return (a.type < b.type || (a.type == b.type && a.hash < b.hash)); +} + +bool CInv::IsKnownType() const +{ + return (type >= 1 && type < ARRAYLEN(ppszTypeName)); +} + +const char* CInv::GetCommand() const +{ + if (!IsKnownType()) + throw std::out_of_range(strprintf("CInv::GetCommand() : type=%d unknown type", type)); + return ppszTypeName[type]; +} + +std::string CInv::ToString() const +{ + return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,20).c_str()); +} + +void CInv::print() const +{ + printf("CInv(%s)\n", ToString().c_str()); +} diff --git a/src/protocol.h b/src/protocol.h index 009f67dfa..53d3eef4d 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -12,6 +12,7 @@ #include "serialize.h" #include +#include "uint256.h" extern bool fTestNet; static inline unsigned short GetDefaultPort(const bool testnet = fTestNet) @@ -120,4 +121,30 @@ class CAddress unsigned int nLastTry; }; +class CInv +{ + public: + CInv(); + CInv(int typeIn, const uint256& hashIn); + CInv(const std::string& strType, const uint256& hashIn); + + IMPLEMENT_SERIALIZE + ( + READWRITE(type); + READWRITE(hash); + ) + + friend bool operator<(const CInv& a, const CInv& b); + + bool IsKnownType() const; + const char* GetCommand() const; + std::string ToString() const; + void print() const; + + // TODO: make private (improves encapsulation) + public: + int type; + uint256 hash; +}; + #endif // __INCLUDED_PROTOCOL_H__ From 98deeaef15dd716a40021831776c5e20aca4605e Mon Sep 17 00:00:00 2001 From: ovdeathiam Date: Mon, 22 Aug 2011 01:55:41 +0300 Subject: [PATCH 11/29] Edited locale/pl/LC_MESSAGES/bitcoin.po via GitHub --- locale/pl/LC_MESSAGES/bitcoin.po | 636 +++++++++++++------------------ 1 file changed, 266 insertions(+), 370 deletions(-) diff --git a/locale/pl/LC_MESSAGES/bitcoin.po b/locale/pl/LC_MESSAGES/bitcoin.po index 7c177b82d..17b5f1046 100644 --- a/locale/pl/LC_MESSAGES/bitcoin.po +++ b/locale/pl/LC_MESSAGES/bitcoin.po @@ -2,10 +2,10 @@ msgid "" msgstr "" "Project-Id-Version: Bitcoin\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-07-14 18:55+0100\n" +"POT-Creation-Date: 2011-06-28 20:11+0100\n" "PO-Revision-Date: \n" -"Last-Translator: Dawid Spiechowicz \n" -"Language-Team: Spiechu \n" +"Last-Translator: Krystian Maksymowicz \n" +"Language-Team: Spiechu , Krystian Maksymowicz \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -18,10 +18,10 @@ msgstr "" "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" "X-Poedit-SearchPath-0: ../../..\n" -#: ../../../src/net.cpp:1615 +#: ../../../src/net.cpp:1590 #, c-format msgid "Unable to bind to port %d on this computer. Bitcoin is probably already running." -msgstr "Nie można powiązać z portem %d tego komputera. Prawdopodobnie program Bitcoin jest już uruchomiony." +msgstr "Powiązanie z portem %d nie powiodło się. Prawdopodobnie Bitcoin jest już uruchomiony." #: ../../../src/init.cpp:162 msgid "Bitcoin version" @@ -29,7 +29,7 @@ msgstr "Wersja Bitcoin" #: ../../../src/init.cpp:163 msgid "Usage:" -msgstr "Użycie:" +msgstr "Zastosowanie:" #: ../../../src/init.cpp:165 msgid "Send command to -server or bitcoind\n" @@ -37,7 +37,7 @@ msgstr "Wyślij polecenie do -server lub bitcoind\n" #: ../../../src/init.cpp:166 msgid "List commands\n" -msgstr "Wyświetl komendy\n" +msgstr "Lista komend\n" #: ../../../src/init.cpp:167 msgid "Get help for a command\n" @@ -53,7 +53,7 @@ msgstr "Określ plik konfiguracyjny (domyślnie: bitcoin.conf)\n" #: ../../../src/init.cpp:170 msgid "Specify pid file (default: bitcoind.pid)\n" -msgstr "Wybierz plik pid (domyślnie: bitcoind.pid)\n" +msgstr "Określ plik pid (domyślnie: bitcoind.pid)\n" #: ../../../src/init.cpp:171 msgid "Generate coins\n" @@ -69,20 +69,22 @@ msgstr "Uruchom zminimalizowany\n" #: ../../../src/init.cpp:174 msgid "Specify data directory\n" -msgstr "Wybierz katalog z danymi\n" +msgstr "Określ katalog danych\n" #: ../../../src/init.cpp:175 msgid "Specify connection timeout (in milliseconds)\n" -msgstr "Ustaw czas upływu połączenia (w milisekundach)\n" +msgstr "Ustaw limit czasu połączenia (w milisekundach)\n" #: ../../../src/init.cpp:176 msgid "Connect through socks4 proxy\n" -msgstr "Połącz przez socks4 proxy\n" +msgstr "Połącz przez proxy socks4\n" +# 2do #: ../../../src/init.cpp:177 msgid "Allow DNS lookups for addnode and connect\n" -msgstr "Umożliwiaj wyszukiwanie DNS dla dodania węzła i połączenia\n" +msgstr "Umożliwiaj wyszukiwanie DNS przy dodawaniu węzła i połączenia\n" +# 2do #: ../../../src/init.cpp:178 msgid "Add a node to connect to\n" msgstr "Dodaj węzeł do którego połączyć\n" @@ -188,37 +190,29 @@ msgstr "Błąd ładowania addr.dat \n" msgid "Error loading blkindex.dat \n" msgstr "Błąd ładowania blkindex.dat \n" -#: ../../../src/init.cpp:394 -msgid "Error loading wallet.dat: Wallet corrupted \n" -msgstr "Błąd ładowania wallet.dat: Portfel uszkodzony \n" - -#: ../../../src/init.cpp:396 -msgid "Error loading wallet.dat: Wallet requires newer version of Bitcoin \n" -msgstr "Błąd ładowania wallet.dat: Portfel wymaga nowszej wersji Bitcoin \n" - -#: ../../../src/init.cpp:398 +#: ../../../src/init.cpp:391 msgid "Error loading wallet.dat \n" msgstr "Błąd ładowania wallet.dat \n" -#: ../../../src/init.cpp:488 +#: ../../../src/init.cpp:481 msgid "Invalid -proxy address" msgstr "Niewłaściwy adres -proxy" -#: ../../../src/init.cpp:513 +#: ../../../src/init.cpp:504 msgid "Invalid amount for -paytxfee=" msgstr "Nieprawidłowa kwota w -paytxfee=" -#: ../../../src/init.cpp:517 +#: ../../../src/init.cpp:508 msgid "Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction." msgstr "Ostrzeżenie: ustawienie -paytxfee jest bardzo wysokie. To jest prowizja transakcji, którą zapłacisz jeżeli wyślesz transakcję." -#: ../../../src/rpc.cpp:2100 -#: ../../../src/rpc.cpp:2102 +#: ../../../src/rpc.cpp:1822 +#: ../../../src/rpc.cpp:1824 #, c-format msgid "To use the %s option" msgstr "Użycie opcji %s" -#: ../../../src/rpc.cpp:2104 +#: ../../../src/rpc.cpp:1826 #, c-format msgid "" "Warning: %s, you must set rpcpassword=\n" @@ -229,7 +223,7 @@ msgstr "" "w pliku konfiguracyjnym: %s\n" "Jeżeli plik nie istnieje, utwórz go z uprawnieniami tylko do odczytu dla właściciela.\n" -#: ../../../src/rpc.cpp:2277 +#: ../../../src/rpc.cpp:1994 #, c-format msgid "" "You must set rpcpassword= in the configuration file:\n" @@ -240,454 +234,368 @@ msgstr "" "%s\n" "Jeżeli plik nie istnieje, utwórz go z uprawnieniami tylko do odczytu dla właściciela." -#: ../../../src/util.cpp:869 +#: ../../../src/util.cpp:874 msgid "Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly." -msgstr "Ostrzeżenie: Sprawdź czy ustawienia daty i czasu komputera są prawidłowe. Jeżeli zegar jest źle ustawiony, Bitcoin nie będzie poprawnie działał." +msgstr "Ostrzeżenie: Sprawdź czy ustawienia daty i czasu komputera są prawidłowe. Jeżeli zegar jest źle ustawiony, Bitcoin nie będzie działał poprawnie." -#: ../../../src/util.cpp:903 +#: ../../../src/util.cpp:908 msgid "beta" msgstr "beta" #: ../../../src/ui.cpp:216 #, c-format msgid "This transaction is over the size limit. You can still send it for a fee of %s, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee?" -msgstr "Ta transakcja jest poza limitem wielkości. W dalszym ciągu możesz wysłać ją z prowizją %s, która dotrze do węzłów przetwarzających twoją transakcję i pomoże utrzymać sieć. Chcesz zapłacić prowizję?" - -#: ../../../src/ui.cpp:259 -#: ../../../src/ui.cpp:1246 -msgid "Enter the current passphrase to the wallet." -msgstr "Wpisz obecne hasło do portfela." - -#: ../../../src/ui.cpp:260 -#: ../../../src/ui.cpp:1182 -#: ../../../src/ui.cpp:1199 -#: ../../../src/ui.cpp:1247 -#: ../../../src/ui.cpp:1273 -#: ../../../src/ui.cpp:1293 -msgid "Passphrase" -msgstr "Hasło" - -#: ../../../src/ui.cpp:266 -msgid "Please supply the current wallet decryption passphrase." -msgstr "Proszę dostarczyć hasło do odszyfrowania portfela." - -#: ../../../src/ui.cpp:274 -#: ../../../src/ui.cpp:1258 -#: ../../../src/ui.cpp:1315 -msgid "The passphrase entered for the wallet decryption was incorrect." -msgstr "Wpisane hasło do odszyfrowania portfela jest nieprawidłowe." +msgstr "Ta transakcja przekracza limit wielkości. W dalszym ciągu możesz ją wysłać z prowizją %s, która dotrze do węzłów przetwarzających twoją transakcję i pomoże utrzymać całą sieć. Chcesz zapłacić prowizję?" -#: ../../../src/ui.cpp:351 +#: ../../../src/ui.cpp:316 msgid "Status" -msgstr "Status" +msgstr "Stan" -#: ../../../src/ui.cpp:352 +#: ../../../src/ui.cpp:317 msgid "Date" msgstr "Data" -#: ../../../src/ui.cpp:353 +#: ../../../src/ui.cpp:318 msgid "Description" msgstr "Opis" -#: ../../../src/ui.cpp:354 +#: ../../../src/ui.cpp:319 msgid "Debit" -msgstr "Obciążenie" +msgstr "Debet" -#: ../../../src/ui.cpp:355 +#: ../../../src/ui.cpp:320 msgid "Credit" -msgstr "Suma" +msgstr "Kredyt" -#: ../../../src/ui.cpp:566 +#: ../../../src/ui.cpp:526 #, c-format msgid "Open for %d blocks" msgstr "Otwórz na %d bloków" -#: ../../../src/ui.cpp:568 +#: ../../../src/ui.cpp:528 #, c-format msgid "Open until %s" msgstr "Otwarte dopóki %s" -#: ../../../src/ui.cpp:574 +#: ../../../src/ui.cpp:534 #, c-format msgid "%d/offline?" msgstr "%d/offline?" -#: ../../../src/ui.cpp:576 +#: ../../../src/ui.cpp:536 #, c-format msgid "%d/unconfirmed" -msgstr "%d/niepotwierdzono" +msgstr "%d/niepotwierdzona" -#: ../../../src/ui.cpp:578 +#: ../../../src/ui.cpp:538 #, c-format msgid "%d confirmations" msgstr "%d potwierdzeń" -#: ../../../src/ui.cpp:663 +#: ../../../src/ui.cpp:623 msgid "Generated" msgstr "Wygenerowano" -#: ../../../src/ui.cpp:671 +#: ../../../src/ui.cpp:631 #, c-format msgid "Generated (%s matures in %d more blocks)" msgstr "Wygenerowano (%s dojrzałych w %d więcej bloków)" -#: ../../../src/ui.cpp:675 +#: ../../../src/ui.cpp:635 msgid "Generated - Warning: This block was not received by any other nodes and will probably not be accepted!" msgstr "Wygenerowano - Ostrzeżenie: Ten blok nie został otrzymany przez żaden inny węzeł i prawdopodobnie nie zostanie zaakceptowany!" -#: ../../../src/ui.cpp:679 +#: ../../../src/ui.cpp:639 msgid "Generated (not accepted)" msgstr "Wygenerowano (nie zaakceptowano)" -#: ../../../src/ui.cpp:689 +#: ../../../src/ui.cpp:649 msgid "From: " msgstr "Od:" -#: ../../../src/ui.cpp:713 +#: ../../../src/ui.cpp:673 msgid "Received with: " msgstr "Otrzymano z:" -#: ../../../src/ui.cpp:759 +#: ../../../src/ui.cpp:719 msgid "Payment to yourself" msgstr "Płatność dla siebie samego" -#: ../../../src/ui.cpp:793 +#: ../../../src/ui.cpp:753 msgid "To: " msgstr "Do:" -#: ../../../src/ui.cpp:1108 +#: ../../../src/ui.cpp:1068 msgid " Generating" msgstr " Generowanie" -#: ../../../src/ui.cpp:1110 +#: ../../../src/ui.cpp:1070 msgid "(not connected)" msgstr "(nie połączony)" -#: ../../../src/ui.cpp:1113 +#: ../../../src/ui.cpp:1073 #, c-format msgid " %d connections %d blocks %d transactions" msgstr " %d połączeń %d bloków %d transakcji" -#: ../../../src/ui.cpp:1170 -msgid "Wallet already encrypted." -msgstr "Portfel już zaszyfrowany." - -#: ../../../src/ui.cpp:1181 -msgid "" -"Enter the new passphrase to the wallet.\n" -"Please use a passphrase of 10 or more random characters, or eight or more words." -msgstr "" -"Wpisz nowe hasło dla portfela.\n" -"Proszę użyć hasła składającego się z 10 lub więcej losowych znaków albo ośmiu lub więcej słów." - -#: ../../../src/ui.cpp:1188 -#: ../../../src/ui.cpp:1281 -msgid "Error: The supplied passphrase was too short." -msgstr "Błąd: Dostarczone hasło jest za krótkie." - -#: ../../../src/ui.cpp:1192 -msgid "" -"WARNING: If you encrypt your wallet and lose your passphrase, you will LOSE ALL OF YOUR BITCOINS!\n" -"Are you sure you wish to encrypt your wallet?" -msgstr "" -"OSTRZEŻENIE: Jeżeli zaszyfrujesz swój portfel i zgubisz hasło, STRACISZ WSZYSTKIE SWOJE BITCOINY!\n" -"Czy jesteś pewny, że chcesz zaszyfrować swój portfel?" - -#: ../../../src/ui.cpp:1198 -msgid "Please re-enter your new wallet passphrase." -msgstr "Proszę powtórzyć nowe hasło do portfela." - -#: ../../../src/ui.cpp:1207 -#: ../../../src/ui.cpp:1303 -msgid "Error: the supplied passphrases didn't match." -msgstr "Błąd: dostarczone hasła się nie zgadzają." - -#: ../../../src/ui.cpp:1217 -msgid "Wallet encryption failed." -msgstr "Szyfrowanie portfela nie powiodło się." - -#: ../../../src/ui.cpp:1224 -msgid "" -"Wallet Encrypted.\n" -"Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer." -msgstr "" -"Portfel zaszyfrowany.\n" -"Pamiętaj, że zaszyfrowanie portfela nie chroni w pełni twoich bitcoinów przed kradzieżą przeprowadzoną przez złośliwe oprogramowanie infekujące twój komputer." - -#: ../../../src/ui.cpp:1235 -msgid "Wallet is unencrypted, please encrypt it first." -msgstr "Portfel jest niezaszyfrowany, proszę najpierw zaszyfrować." - -#: ../../../src/ui.cpp:1272 -msgid "Enter the new passphrase for the wallet." -msgstr "Wprowadź nowe hasło dla portfela." - -#: ../../../src/ui.cpp:1292 -msgid "Re-enter the new passphrase for the wallet." -msgstr "Powtórnie wprowadź nowe hasło dla portfela." - -#: ../../../src/ui.cpp:1324 -msgid "Wallet Passphrase Changed." -msgstr "Hasło dla portfela zostało zmienione." - -#: ../../../src/ui.cpp:1381 -#: ../../../src/ui.cpp:2816 +#: ../../../src/ui.cpp:1178 +#: ../../../src/ui.cpp:2571 msgid "New Receiving Address" -msgstr "Nowy Adres Odbiorczy" +msgstr "Nowy adres odbiorczy" -#: ../../../src/ui.cpp:1382 -#: ../../../src/ui.cpp:2817 +#: ../../../src/ui.cpp:1179 +#: ../../../src/ui.cpp:2572 msgid "" "You should use a new address for each payment you receive.\n" "\n" "Label" msgstr "" -"Powinieneś użyć nowego adresu dla każdej płatności, którą otrzymasz.\n" +"Powinieneś używać nowych adresów dla każdej otrzymywanej płatności.\n" "\n" "Etykieta" -#: ../../../src/ui.cpp:1466 +#: ../../../src/ui.cpp:1251 msgid "Status: " msgstr "Status:" -#: ../../../src/ui.cpp:1471 +#: ../../../src/ui.cpp:1256 msgid ", has not been successfully broadcast yet" msgstr ", nie został jeszcze prawidłowo rozgłoszony" -#: ../../../src/ui.cpp:1473 +#: ../../../src/ui.cpp:1258 #, c-format msgid ", broadcast through %d node" msgstr ", rozgłasza przez %d węzeł" -#: ../../../src/ui.cpp:1475 +#: ../../../src/ui.cpp:1260 #, c-format msgid ", broadcast through %d nodes" msgstr ", rozgłasza przez %d węzłów" -#: ../../../src/ui.cpp:1479 +#: ../../../src/ui.cpp:1264 msgid "Date: " msgstr "Data:" -#: ../../../src/ui.cpp:1487 +#: ../../../src/ui.cpp:1272 msgid "Source: Generated
" msgstr "Źródło: Wygenerowano
" -#: ../../../src/ui.cpp:1493 -#: ../../../src/ui.cpp:1511 +#: ../../../src/ui.cpp:1278 +#: ../../../src/ui.cpp:1296 msgid "From: " msgstr "Od:" -#: ../../../src/ui.cpp:1511 +#: ../../../src/ui.cpp:1296 msgid "unknown" msgstr "nieznany" -#: ../../../src/ui.cpp:1512 -#: ../../../src/ui.cpp:1536 -#: ../../../src/ui.cpp:1595 +#: ../../../src/ui.cpp:1297 +#: ../../../src/ui.cpp:1321 +#: ../../../src/ui.cpp:1380 msgid "To: " msgstr "Do:" -#: ../../../src/ui.cpp:1515 +#: ../../../src/ui.cpp:1300 msgid " (yours, label: " msgstr " (twoja, etykieta: " -#: ../../../src/ui.cpp:1517 +#: ../../../src/ui.cpp:1302 msgid " (yours)" msgstr " (twoja)" -#: ../../../src/ui.cpp:1554 -#: ../../../src/ui.cpp:1566 -#: ../../../src/ui.cpp:1612 -#: ../../../src/ui.cpp:1629 +#: ../../../src/ui.cpp:1339 +#: ../../../src/ui.cpp:1351 +#: ../../../src/ui.cpp:1397 +#: ../../../src/ui.cpp:1414 msgid "Credit: " -msgstr "Suma:" +msgstr "Kredyt:" -#: ../../../src/ui.cpp:1556 +#: ../../../src/ui.cpp:1341 #, c-format msgid "(%s matures in %d more blocks)" msgstr "(%s dojrzałych w %d więcej bloków)" -#: ../../../src/ui.cpp:1558 +#: ../../../src/ui.cpp:1343 msgid "(not accepted)" msgstr "(nie zaakceptowano)" -#: ../../../src/ui.cpp:1603 -#: ../../../src/ui.cpp:1611 -#: ../../../src/ui.cpp:1626 +#: ../../../src/ui.cpp:1388 +#: ../../../src/ui.cpp:1396 +#: ../../../src/ui.cpp:1411 msgid "Debit: " -msgstr "Obciążenie:" +msgstr "Debet:" -#: ../../../src/ui.cpp:1617 +#: ../../../src/ui.cpp:1402 msgid "Transaction fee: " msgstr "Prowizja transakcji:" -#: ../../../src/ui.cpp:1633 +#: ../../../src/ui.cpp:1418 msgid "Net amount: " msgstr "Kwota netto:" -#: ../../../src/ui.cpp:1640 +#: ../../../src/ui.cpp:1425 msgid "Message:" msgstr "Wiadomość:" -#: ../../../src/ui.cpp:1642 +#: ../../../src/ui.cpp:1427 msgid "Comment:" msgstr "Komentarz:" -#: ../../../src/ui.cpp:1645 +#: ../../../src/ui.cpp:1430 msgid "Generated coins must wait 120 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, it will change to \"not accepted\" and not be spendable. This may occasionally happen if another node generates a block within a few seconds of yours." -msgstr "Wygenerowane monety muszą poczekać 120 bloków zanim mogą zostać wydane. Gdy wygenerowałeś ten blok, został rozgłoszony do sieci z przeznaczeniem do dodania do łańcucha bloków. Jeżeli nie uda się dodać bloku do łańcucha, zostanie oznaczony jako \"nie zaakceptowany\" i nie będzie mógł zostać wydany. Sporadycznie dzieje się tak jeżeli inny węzeł wygeneruje blok nie dalej niż kilka sekund od ciebie." +msgstr "Wygenerowane monety muszą poczekać 120 bloków zanim będą mogły być wydane. Wygenerowany blok został został rozgłoszony w sieci z przeznaczeniem dodawania nowych bloków do łańcucha. Jeżeli nie uda się go dodać do łańcucha, zostanie oznaczony jako \"nie zaakceptowany\" i nie będzie mógł być wydany. Sporadycznie dzieje się tak jeżeli inny węzeł wygeneruje blok nie dalej niż kilka sekund od ciebie." -#: ../../../src/ui.cpp:1825 +#: ../../../src/ui.cpp:1610 msgid "Cannot write autostart/bitcoin.desktop file" msgstr "Nie mogę zapisać pliku autostart/bitcoin.desktop" -#: ../../../src/ui.cpp:1861 +#: ../../../src/ui.cpp:1646 msgid "Main" msgstr "Główne" -#: ../../../src/ui.cpp:1871 +#: ../../../src/ui.cpp:1656 msgid "&Start Bitcoin on window system startup" msgstr "&Uruchom Bitcoin przy starcie systemu" -#: ../../../src/ui.cpp:1878 +#: ../../../src/ui.cpp:1663 msgid "&Minimize on close" msgstr "&Minimalizuj przy zamknięciu" -#: ../../../src/ui.cpp:2020 +#: ../../../src/ui.cpp:1805 #, c-format msgid "version %s" msgstr "wersja %s" -#: ../../../src/ui.cpp:2143 +#: ../../../src/ui.cpp:1928 msgid "Error in amount " msgstr "Nieprawidłowa kwota" -#: ../../../src/ui.cpp:2143 -#: ../../../src/ui.cpp:2148 -#: ../../../src/ui.cpp:2153 -#: ../../../src/ui.cpp:2202 -#: ../../../src/uibase.cpp:61 +#: ../../../src/ui.cpp:1928 +#: ../../../src/ui.cpp:1933 +#: ../../../src/ui.cpp:1938 +#: ../../../src/ui.cpp:1973 +#: ../../../src/uibase.cpp:55 msgid "Send Coins" msgstr "Wyślij Monety" -#: ../../../src/ui.cpp:2148 +#: ../../../src/ui.cpp:1933 msgid "Amount exceeds your balance " msgstr "Kwota przekracza twój stan konta" -#: ../../../src/ui.cpp:2153 +#: ../../../src/ui.cpp:1938 msgid "Total exceeds your balance when the " msgstr "Przekroczenie twojego stanu konta gdy" -#: ../../../src/ui.cpp:2153 +#: ../../../src/ui.cpp:1938 msgid " transaction fee is included " msgstr " prowizja jest wliczona" -#: ../../../src/ui.cpp:2176 +#: ../../../src/ui.cpp:1956 msgid "Payment sent " msgstr "Wysłano płatność" -#: ../../../src/ui.cpp:2176 -#: ../../../src/ui.cpp:2185 -#: ../../../src/ui.cpp:2336 -#: ../../../src/ui.cpp:2500 -#: ../../../src/wallet.cpp:1097 +#: ../../../src/ui.cpp:1956 +#: ../../../src/ui.cpp:1961 +#: ../../../src/ui.cpp:2107 +#: ../../../src/ui.cpp:2260 +#: ../../../src/wallet.cpp:924 msgid "Sending..." msgstr "Wysyłanie..." -#: ../../../src/ui.cpp:2202 +#: ../../../src/ui.cpp:1973 msgid "Invalid address " msgstr "Nieprawidłowy adres" -#: ../../../src/ui.cpp:2257 +#: ../../../src/ui.cpp:2028 #, c-format msgid "Sending %s to %s" msgstr "Wysyłanie %s do %s" -#: ../../../src/ui.cpp:2330 -#: ../../../src/ui.cpp:2363 +#: ../../../src/ui.cpp:2101 +#: ../../../src/ui.cpp:2134 msgid "CANCELLED" msgstr "ANULOWANO" -#: ../../../src/ui.cpp:2334 +#: ../../../src/ui.cpp:2105 msgid "Cancelled" msgstr "Anulowano" -#: ../../../src/ui.cpp:2336 +#: ../../../src/ui.cpp:2107 msgid "Transfer cancelled " -msgstr "Transfer anulowano" +msgstr "Transfer anulowany" -#: ../../../src/ui.cpp:2389 +#: ../../../src/ui.cpp:2160 msgid "Error: " msgstr "Błąd:" -#: ../../../src/ui.cpp:2403 -#: ../../../src/ui.cpp:2474 -#: ../../../src/wallet.cpp:1116 +#: ../../../src/ui.cpp:2174 +#: ../../../src/ui.cpp:2245 +#: ../../../src/wallet.cpp:943 msgid "Insufficient funds" msgstr "Niewystarczające fundusze" -#: ../../../src/ui.cpp:2408 +#: ../../../src/ui.cpp:2179 msgid "Connecting..." msgstr "Łączenie..." -#: ../../../src/ui.cpp:2413 +#: ../../../src/ui.cpp:2184 msgid "Unable to connect" msgstr "Nie można połączyć" -#: ../../../src/ui.cpp:2418 +#: ../../../src/ui.cpp:2189 msgid "Requesting public key..." msgstr "Żądanie klucza publicznego..." -#: ../../../src/ui.cpp:2430 +#: ../../../src/ui.cpp:2201 msgid "Received public key..." msgstr "Otrzymano klucz publiczny..." -#: ../../../src/ui.cpp:2444 +#: ../../../src/ui.cpp:2215 msgid "Recipient is not accepting transactions sent by IP address" msgstr "Adresat nie akceptuje transakcji wysyłanych przez adres IP" -#: ../../../src/ui.cpp:2446 +#: ../../../src/ui.cpp:2217 msgid "Transfer was not accepted" msgstr "Transfer nie został zaakceptowany" -#: ../../../src/ui.cpp:2455 +#: ../../../src/ui.cpp:2226 msgid "Invalid response received" msgstr "Otrzymano niepoprawną odpowiedź" -#: ../../../src/ui.cpp:2470 +#: ../../../src/ui.cpp:2241 msgid "Creating transaction..." msgstr "Tworzenie transakcji..." -#: ../../../src/ui.cpp:2489 +#: ../../../src/ui.cpp:2253 #, c-format msgid "This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds" -msgstr "Ta transakcja wymaga prowizji co najmniej %s z uwagi na kwotę, złożoność lub użycie niedawno otrzymanych funduszy" +msgstr "Ta transakcja wymaga prowizji co najmniej %s z uwagi na jej kwotę, złożoność lub wykorzystanie niedawno otrzymanych funduszy" -#: ../../../src/ui.cpp:2491 +#: ../../../src/ui.cpp:2255 msgid "Transaction creation failed" msgstr "Błąd tworzenia transakcji " -#: ../../../src/ui.cpp:2502 +#: ../../../src/ui.cpp:2262 msgid "Transaction aborted" -msgstr "Transakcję przerwano" +msgstr "Przerwano transakcję" -#: ../../../src/ui.cpp:2510 +#: ../../../src/ui.cpp:2270 msgid "Lost connection, transaction cancelled" msgstr "Utracono połączenie, transakcja anulowana" -#: ../../../src/ui.cpp:2526 +#: ../../../src/ui.cpp:2286 msgid "Sending payment..." msgstr "Wysyłanie płatności..." -#: ../../../src/ui.cpp:2532 +#: ../../../src/ui.cpp:2292 msgid "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." msgstr "Transakcja została odrzucona. Może się tak zdarzyć jeżeli część monet w twoim portfelu zostało wydanych, np. gdy użyto kopii pliku wallet.dat i monety zostały wydane w kopii, a tutaj nie zostały oznaczone jako wydane." -#: ../../../src/ui.cpp:2541 +#: ../../../src/ui.cpp:2301 msgid "Waiting for confirmation..." msgstr "Oczekiwanie na potwierdzenie..." -#: ../../../src/ui.cpp:2559 +#: ../../../src/ui.cpp:2319 msgid "" "The payment was sent, but the recipient was unable to verify it.\n" "The transaction is recorded and will credit to the recipient,\n" @@ -697,86 +605,86 @@ msgstr "" "Transakcja została zarejestrowana i zostanie przypisana do odbiorcy,\n" "ale informacja w komentarzu będzie pusta." -#: ../../../src/ui.cpp:2568 +#: ../../../src/ui.cpp:2328 msgid "Payment was sent, but an invalid response was received" msgstr "Płatność została wysłana, ale otrzymano nieprawidłową odpowiedź" -#: ../../../src/ui.cpp:2574 +#: ../../../src/ui.cpp:2334 msgid "Payment completed" msgstr "Płatność zakończona" -#: ../../../src/ui.cpp:2616 -#: ../../../src/ui.cpp:2764 -#: ../../../src/ui.cpp:2804 +#: ../../../src/ui.cpp:2376 +#: ../../../src/ui.cpp:2522 +#: ../../../src/ui.cpp:2559 msgid "Name" msgstr "Nazwa" -#: ../../../src/ui.cpp:2617 -#: ../../../src/ui.cpp:2764 -#: ../../../src/ui.cpp:2804 +#: ../../../src/ui.cpp:2377 +#: ../../../src/ui.cpp:2522 +#: ../../../src/ui.cpp:2559 msgid "Address" msgstr "Adres" -#: ../../../src/ui.cpp:2619 -#: ../../../src/ui.cpp:2776 +#: ../../../src/ui.cpp:2379 +#: ../../../src/ui.cpp:2534 msgid "Label" msgstr "Etykieta" -#: ../../../src/ui.cpp:2620 -#: ../../../src/uibase.cpp:847 +#: ../../../src/ui.cpp:2380 +#: ../../../src/uibase.cpp:837 msgid "Bitcoin Address" msgstr "Adres Bitcoin" -#: ../../../src/ui.cpp:2746 +#: ../../../src/ui.cpp:2504 msgid "This is one of your own addresses for receiving payments and cannot be entered in the address book. " -msgstr "To jest jeden z twoich adresów na otrzymywane płatności i nie może zostać wpisany do księgi adresowej." +msgstr "To jest jeden z twoich adresów na otrzymywane płatności i nie może zostać wpisany do książki adresowej." -#: ../../../src/ui.cpp:2764 -#: ../../../src/ui.cpp:2770 +#: ../../../src/ui.cpp:2522 +#: ../../../src/ui.cpp:2528 msgid "Edit Address" -msgstr "Edytuj Adres" +msgstr "Edytuj adres" -#: ../../../src/ui.cpp:2776 +#: ../../../src/ui.cpp:2534 msgid "Edit Address Label" -msgstr "Edytuj Etykietę Adresu" +msgstr "Edytuj etykietę adresu" -#: ../../../src/ui.cpp:2804 -#: ../../../src/ui.cpp:2810 +#: ../../../src/ui.cpp:2559 +#: ../../../src/ui.cpp:2565 msgid "Add Address" -msgstr "Dodaj Adres" +msgstr "Dodaj adres" -#: ../../../src/ui.cpp:2898 +#: ../../../src/ui.cpp:2642 msgid "Bitcoin" msgstr "Bitcoin" -#: ../../../src/ui.cpp:2900 +#: ../../../src/ui.cpp:2644 msgid "Bitcoin - Generating" msgstr "Bitcoin - Generowanie" -#: ../../../src/ui.cpp:2902 +#: ../../../src/ui.cpp:2646 msgid "Bitcoin - (not connected)" msgstr "Bitcoin - (nie połączony)" -#: ../../../src/ui.cpp:2981 +#: ../../../src/ui.cpp:2725 msgid "&Open Bitcoin" msgstr "&Otwórz Bitcoin" -#: ../../../src/ui.cpp:2982 +#: ../../../src/ui.cpp:2726 msgid "&Send Bitcoins" msgstr "&Wyślij Bitcoiny" -#: ../../../src/ui.cpp:2983 +#: ../../../src/ui.cpp:2727 msgid "O&ptions..." msgstr "O&pcje..." -#: ../../../src/ui.cpp:2986 +#: ../../../src/ui.cpp:2730 #: ../../../src/uibase.cpp:25 msgid "E&xit" msgstr "W&yjście" -#: ../../../src/ui.cpp:3212 +#: ../../../src/ui.cpp:2956 msgid "Program has crashed and will terminate. " -msgstr "Program uległ awarii i zostanie przerwany." +msgstr "Program uległ awarii i zostanie zamknięty." #: ../../../src/main.cpp:1430 msgid "Warning: Disk space is low " @@ -788,162 +696,154 @@ msgstr "&Plik" #: ../../../src/uibase.cpp:32 msgid "&Your Receiving Addresses..." -msgstr "&Twój Adres Odbiorczy..." +msgstr "&Twój adres odbiorczy..." -#: ../../../src/uibase.cpp:35 -msgid "&Encrypt Wallet..." -msgstr "&Zaszyfruj portfel..." - -#: ../../../src/uibase.cpp:38 -msgid "&Change Wallet Encryption Passphrase..." -msgstr "&Zmień hasło szyfrowania portfela..." - -#: ../../../src/uibase.cpp:42 +#: ../../../src/uibase.cpp:36 msgid "&Options..." msgstr "&Opcje..." -#: ../../../src/uibase.cpp:45 +#: ../../../src/uibase.cpp:39 msgid "&Settings" msgstr "&Ustawienia" -#: ../../../src/uibase.cpp:49 +#: ../../../src/uibase.cpp:43 msgid "&About..." msgstr "&O programie..." -#: ../../../src/uibase.cpp:52 +#: ../../../src/uibase.cpp:46 msgid "&Help" msgstr "&Pomoc" -#: ../../../src/uibase.cpp:62 +#: ../../../src/uibase.cpp:56 msgid "Address Book" -msgstr "Księga Adresowa" +msgstr "Książka adresowa" -#: ../../../src/uibase.cpp:75 +#: ../../../src/uibase.cpp:69 msgid "Your Bitcoin Address:" -msgstr "Twój Adres Bitcoin:" +msgstr "Twój adres Bitcoin:" -#: ../../../src/uibase.cpp:82 +#: ../../../src/uibase.cpp:76 msgid " &New... " msgstr " &Nowy..." -#: ../../../src/uibase.cpp:85 -#: ../../../src/uibase.cpp:790 -#: ../../../src/uibase.cpp:893 +#: ../../../src/uibase.cpp:79 +#: ../../../src/uibase.cpp:780 +#: ../../../src/uibase.cpp:883 msgid " &Copy to Clipboard " msgstr " &Kopiuj do schowka " -#: ../../../src/uibase.cpp:99 +#: ../../../src/uibase.cpp:93 msgid "Balance:" msgstr "Saldo:" -#: ../../../src/uibase.cpp:115 +#: ../../../src/uibase.cpp:109 msgid " All" msgstr " Wszystko" -#: ../../../src/uibase.cpp:115 +#: ../../../src/uibase.cpp:109 msgid " Sent" -msgstr "Wysłano" +msgstr " Wysłano" -#: ../../../src/uibase.cpp:115 +#: ../../../src/uibase.cpp:109 msgid " Received" -msgstr "Otrzymano" +msgstr " Otrzymano" -#: ../../../src/uibase.cpp:115 +#: ../../../src/uibase.cpp:109 msgid " In Progress" -msgstr "W Trakcie" +msgstr "W realizacji" -#: ../../../src/uibase.cpp:136 +#: ../../../src/uibase.cpp:130 msgid "All Transactions" -msgstr "Wszystkie Transakcje" +msgstr "Wszystkie transakcje" -#: ../../../src/uibase.cpp:147 +#: ../../../src/uibase.cpp:141 msgid "Sent/Received" -msgstr "Wysłano/Otrzymano" +msgstr "Wysłane/Otrzymane" -#: ../../../src/uibase.cpp:158 +#: ../../../src/uibase.cpp:152 msgid "Sent" -msgstr "Wysłano" +msgstr "Wysłane" -#: ../../../src/uibase.cpp:169 +#: ../../../src/uibase.cpp:163 msgid "Received" -msgstr "Otrzymano" - -#: ../../../src/uibase.cpp:312 -#: ../../../src/uibase.cpp:453 -#: ../../../src/uibase.cpp:552 -#: ../../../src/uibase.cpp:732 -#: ../../../src/uibase.cpp:793 -#: ../../../src/uibase.cpp:902 -#: ../../../src/uibase.cpp:991 +msgstr "Otrzymane" + +#: ../../../src/uibase.cpp:302 +#: ../../../src/uibase.cpp:443 +#: ../../../src/uibase.cpp:542 +#: ../../../src/uibase.cpp:722 +#: ../../../src/uibase.cpp:783 +#: ../../../src/uibase.cpp:892 +#: ../../../src/uibase.cpp:981 msgid "OK" msgstr "OK" -#: ../../../src/uibase.cpp:355 +#: ../../../src/uibase.cpp:345 msgid "&Start Bitcoin on system startup" msgstr "&Uruchom Bitcoin wraz ze startem systemu" -#: ../../../src/uibase.cpp:358 +#: ../../../src/uibase.cpp:348 msgid "&Minimize to the tray instead of the taskbar" -msgstr "&Zminimalizuj do traya zamiast do paska zadań" +msgstr "&Minimalizuj do obszaru powiadomień zamiast paska zadań" -#: ../../../src/uibase.cpp:361 +#: ../../../src/uibase.cpp:351 msgid "Map port using &UPnP" msgstr "Mapuj port używając &UPnP" -#: ../../../src/uibase.cpp:364 +#: ../../../src/uibase.cpp:354 msgid "M&inimize to the tray on close" -msgstr "Zm&inimalizuj do traya przy zamknięciu" +msgstr "M&inimalizuj do obszaru powiadomień przy zamknięciu" -#: ../../../src/uibase.cpp:370 +#: ../../../src/uibase.cpp:360 msgid "&Connect through socks4 proxy: " -msgstr "&Połącz przez socks4 proxy:" +msgstr "&Połącz przez proxy socks4:" -#: ../../../src/uibase.cpp:381 +#: ../../../src/uibase.cpp:371 msgid "Proxy &IP:" msgstr "Proxy &IP:" -#: ../../../src/uibase.cpp:389 +#: ../../../src/uibase.cpp:379 msgid " &Port:" msgstr " &Port:" -#: ../../../src/uibase.cpp:402 +#: ../../../src/uibase.cpp:392 msgid "Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended." -msgstr "Opcjonalna prowizja określona dla KB transakcji, która zapewni, że twoje transakcje będą szybko przetworzone. Większość transakcji to 1KB. Rekomendowana prowizja to 0.01." +msgstr "Opcjonalna prowizja określona na każdy KB transakcji, zapewniająca szybkie przetworzenie. Większość transakcji to 1KB. Rekomendowana prowizja to 0.01." -#: ../../../src/uibase.cpp:409 +#: ../../../src/uibase.cpp:399 msgid "Pay transaction fee:" -msgstr "Płać prowizję transakcji:" +msgstr "Płać prowizję od transakcji:" -#: ../../../src/uibase.cpp:430 +#: ../../../src/uibase.cpp:420 msgid "// [don't translate] Test panel 2 for future expansion" msgstr "" -#: ../../../src/uibase.cpp:434 +#: ../../../src/uibase.cpp:424 msgid "// [don't translate] Let's not start multiple pages until the first page is filled up" msgstr "" -#: ../../../src/uibase.cpp:456 -#: ../../../src/uibase.cpp:678 -#: ../../../src/uibase.cpp:737 -#: ../../../src/uibase.cpp:796 -#: ../../../src/uibase.cpp:905 -#: ../../../src/uibase.cpp:994 +#: ../../../src/uibase.cpp:446 +#: ../../../src/uibase.cpp:668 +#: ../../../src/uibase.cpp:727 +#: ../../../src/uibase.cpp:786 +#: ../../../src/uibase.cpp:895 +#: ../../../src/uibase.cpp:984 msgid "Cancel" msgstr "Anuluj" -#: ../../../src/uibase.cpp:459 +#: ../../../src/uibase.cpp:449 msgid "&Apply" msgstr "&Zastosuj" -#: ../../../src/uibase.cpp:518 +#: ../../../src/uibase.cpp:508 msgid "Bitcoin " -msgstr "Bitcoin" +msgstr "Bitcoin " -#: ../../../src/uibase.cpp:524 +#: ../../../src/uibase.cpp:514 msgid "version" msgstr "wersja" -#: ../../../src/uibase.cpp:535 +#: ../../../src/uibase.cpp:525 msgid "" "Copyright (c) 2009-2011 Bitcoin Developers\n" "\n" @@ -967,39 +867,39 @@ msgstr "" "OpenSSL Toolkit (http://www.openssl.org/) i oprogramowanie kryptograficzne napisane przez \n" "Erica Younga (eay@cryptsoft.com) oraz oprogramowanie UPnP napisane przez Thomasa Bernarda." -#: ../../../src/uibase.cpp:591 +#: ../../../src/uibase.cpp:581 msgid "Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)" msgstr "Wprowadź adres Bitcoin (np. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)" -#: ../../../src/uibase.cpp:605 +#: ../../../src/uibase.cpp:595 msgid "Pay &To:" -msgstr "Wpłać &Dla:" +msgstr "Wpłać &dla:" -#: ../../../src/uibase.cpp:620 +#: ../../../src/uibase.cpp:610 msgid "&Paste" msgstr "&Wklej" -#: ../../../src/uibase.cpp:623 +#: ../../../src/uibase.cpp:613 msgid " Address &Book..." -msgstr " Księga &Adresowa..." +msgstr " Książka &adresowa..." -#: ../../../src/uibase.cpp:630 +#: ../../../src/uibase.cpp:620 msgid "&Amount:" -msgstr "&Kwota:" +msgstr "&Saldo:" -#: ../../../src/uibase.cpp:640 +#: ../../../src/uibase.cpp:630 msgid "T&ransfer:" msgstr "T&ransfer:" -#: ../../../src/uibase.cpp:646 +#: ../../../src/uibase.cpp:636 msgid " Standard" msgstr " Standard" -#: ../../../src/uibase.cpp:673 +#: ../../../src/uibase.cpp:663 msgid "&Send" msgstr "&Wyślij" -#: ../../../src/uibase.cpp:721 +#: ../../../src/uibase.cpp:711 msgid "" "\n" "\n" @@ -1009,74 +909,70 @@ msgstr "" "\n" "Łączenie..." -#: ../../../src/uibase.cpp:771 +#: ../../../src/uibase.cpp:761 msgid "These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. The highlighted address is displayed in the main window." -msgstr "To są twoje adresy Bitcoin dla otrzymywania płatności. Możesz chcieć podać różne dla każdego płacącego aby kontrolować kto ci płaci. Wyróżniony adres będzie wyświetlany w oknie głównym." +msgstr "To są twoje adresy Bitcoin dla otrzymywania płatności. Możesz chcieć podawać inny dla każdego płacącego aby kontrolować kto ci płaci. Wyróżniony adres będzie wyświetlany w oknie głównym." -#: ../../../src/uibase.cpp:784 -#: ../../../src/uibase.cpp:896 +#: ../../../src/uibase.cpp:774 +#: ../../../src/uibase.cpp:886 msgid "&Edit..." msgstr "&Edytuj..." -#: ../../../src/uibase.cpp:787 -#: ../../../src/uibase.cpp:899 +#: ../../../src/uibase.cpp:777 +#: ../../../src/uibase.cpp:889 msgid " &New Address... " -msgstr " &Nowy Adres..." +msgstr " &Nowy adres..." -#: ../../../src/uibase.cpp:859 +#: ../../../src/uibase.cpp:849 msgid "Sending" msgstr "Wysyłanie" -#: ../../../src/uibase.cpp:867 +#: ../../../src/uibase.cpp:857 msgid "These are your Bitcoin addresses for receiving payments. You can give a different one to each sender to keep track of who is paying you. The highlighted address will be displayed in the main window." msgstr "To są twoje adresy Bitcoin dla otrzymywania płatności. Możesz podać różne dla każdego płacącego aby kontrolować kto ci płaci. Wyróżniony adres będzie wyświetlany w oknie głównym." -#: ../../../src/uibase.cpp:880 +#: ../../../src/uibase.cpp:870 msgid "Receiving" msgstr "Otrzymywanie" -#: ../../../src/uibase.cpp:890 +#: ../../../src/uibase.cpp:880 msgid "&Delete" msgstr "&Usuń" -#: ../../../src/wallet.cpp:1081 -msgid "Error: Wallet locked, unable to create transaction " -msgstr "Błąd: Portfel zablokowany, nie można utworzyć transakcji" - -#: ../../../src/wallet.cpp:1089 +#: ../../../src/wallet.cpp:917 #, c-format msgid "Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds " msgstr "Błąd: Ta transakcja wymaga prowizji co najmniej %s z uwagi na kwotę, złożoność lub użycie niedawno otrzymanych funduszy" -#: ../../../src/wallet.cpp:1091 +#: ../../../src/wallet.cpp:919 msgid "Error: Transaction creation failed " msgstr "Błąd: Nie udało się utworzyć transakcji" -#: ../../../src/wallet.cpp:1101 +#: ../../../src/wallet.cpp:928 msgid "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." msgstr "Błąd: Transakcja została odrzucona. Może się tak zdarzyć jeżeli część monet w twoim portfelu zostało wydanych, np. gdy użyto kopii pliku wallet.dat i monety zostały wydane w kopii, a tutaj nie zostały oznaczone jako wydane." -#: ../../../src/wallet.cpp:1114 +#: ../../../src/wallet.cpp:941 msgid "Invalid amount" msgstr "Niewłaściwa kwota" -#: ../../../src/wallet.cpp:1121 +#: ../../../src/wallet.cpp:948 msgid "Invalid bitcoin address" msgstr "Niewłaściwy adres bitcoin" -#: ../../../src/uibase.h:151 +#: ../../../src/uibase.h:147 msgid "Transaction Details" -msgstr "Szczegóły Transakcji" +msgstr "Szczegóły transakcji" -#: ../../../src/uibase.h:203 +#: ../../../src/uibase.h:199 msgid "Options" msgstr "Opcje" -#: ../../../src/uibase.h:232 +#: ../../../src/uibase.h:228 msgid "About Bitcoin" msgstr "O Bitcoin" -#: ../../../src/uibase.h:341 +#: ../../../src/uibase.h:337 msgid "Your Bitcoin Addresses" -msgstr "Twoje Adresy Bitcoin" +msgstr "Twoje adresy bitcoin" From b4ada906c03111404c29b115ab37afbad92f4cf1 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 12 Aug 2011 00:20:07 +0200 Subject: [PATCH 12/29] Upgrade dependancies and tweak build process. * Upgrade to use miniupnpc 1.6 * Upgrade to wxWidgets 2.9.2 * Upgrade to Bost 1.47 for Win32 Builds --- contrib/gitian-win32.yml | 42 ++++++-------- contrib/gitian.yml | 23 +++----- contrib/wx-patches/README | 4 -- contrib/wx-patches/toplevel.cpp.diff | 86 ---------------------------- contrib/wx-patches/toplevel.h.diff | 9 --- doc/build-msw.txt | 36 ++++++------ doc/build-osx.txt | 18 +++--- doc/build-unix.txt | 21 ++++--- src/makefile.linux-mingw | 21 ++++--- src/makefile.mingw | 28 ++++----- src/net.cpp | 15 +---- 11 files changed, 88 insertions(+), 215 deletions(-) delete mode 100644 contrib/wx-patches/README delete mode 100644 contrib/wx-patches/toplevel.cpp.diff delete mode 100644 contrib/wx-patches/toplevel.h.diff diff --git a/contrib/gitian-win32.yml b/contrib/gitian-win32.yml index 07d31c717..d4b0843e7 100644 --- a/contrib/gitian-win32.yml +++ b/contrib/gitian-win32.yml @@ -14,17 +14,15 @@ remotes: - "url": "https://github.com/bitcoin/bitcoin.git" "dir": "bitcoin" files: -- "wxWidgets-2.9.1.tar.bz2" -- "boost_1_43_0.tar.bz2" +- "wxWidgets-2.9.2.tar.bz2" +- "boost_1_47_0.tar.bz2" - "openssl-1.0.0d.tar.gz" -- "db-4.7.25.NC.tar.gz" -- "upnpc-exe-win32-20110215.zip" -- "miniupnpc-1.5.20110215.tar.gz" -- "WSPiApi.h" +- "db-4.8.30.NC.tar.gz" +- "miniupnpc-1.6.tar.gz" script: | # - tar xjf wxWidgets-2.9.1.tar.bz2 - cd wxWidgets-2.9.1 + tar xjf wxWidgets-2.9.2.tar.bz2 + cd wxWidgets-2.9.2 ./configure --host=i586-mingw32msvc --build=i686-linux --disable-shared --enable-monolithic --without-libpng --disable-svg perl -i -p -e "s/__TIME__/\"$REFERENCE_TIME\"/;s/__DATE__/\"$REFERENCE_DATE\"/" include/wx/chartype.h make $MAKEOPTS @@ -36,14 +34,14 @@ script: | make cd .. # - tar xzf db-4.7.25.NC.tar.gz - cd db-4.7.25.NC/build_unix + tar xzf db-4.8.30.NC.tar.gz + cd db-4.8.30.NC/build_unix ../dist/configure --enable-mingw --enable-cxx --host=i586-mingw32msvc CFLAGS="-I/usr/i586-mingw32msvc/include" make $MAKEOPTS cd ../.. # - tar xjf boost_1_43_0.tar.bz2 - cd boost_1_43_0 + tar xjf boost_1_47_0.tar.bz2 + cd boost_1_47_0 echo "using gcc : 4.4 : i586-mingw32msvc-g++ : i586-mingw32msvc-windres @@ -53,16 +51,13 @@ script: | ./bjam toolset=gcc target-os=windows threadapi=win32 threading=multi --user-config=user-config.jam --without-mpi --without-python -sNO_BZIP2=1 -sNO_ZLIB=1 --layout=tagged --build-type=complete $MAKEOPTS stage cd .. # - mkdir upnpc-exe-win32-20110215 - cd upnpc-exe-win32-20110215 - unzip ../upnpc-exe-win32-20110215.zip - mkdir miniupnpc - cd miniupnpc - tar xzf ../../miniupnpc-1.5.20110215.tar.gz - mv ./miniupnpc-1.5.20110215/* ./ - cd ../.. - # - cp WSPiApi.h $HOME/build + tar xzf miniupnpc-1.6.tar.gz + cd miniupnpc-1.6 + sed 's/dllwrap -k --driver-name gcc/$(DLLWRAP) -k --driver-name $(CC)/' -i Makefile.mingw + sed 's|wingenminiupnpcstrings $< $@|./wingenminiupnpcstrings $< $@|' -i Makefile.mingw + make -f Makefile.mingw DLLWRAP=i586-mingw32msvc-dllwrap CC=i586-mingw32msvc-gcc AR=i586-mingw32msvc-ar + cd .. + mv miniupnpc-1.6 miniupnpc # cd bitcoin mkdir -p $OUTDIR/src @@ -72,8 +67,7 @@ script: | cp $OUTDIR/src/doc/README_windows.txt $OUTDIR/readme.txt cp $OUTDIR/src/COPYING $OUTDIR/license.txt cd src - sed 's/$(DEBUGFLAGS)//' < makefile.linux-mingw > makefile.linux-mingw.2 && mv makefile.linux-mingw.2 makefile.linux-mingw - sed 's|//#include |#include |' < net.cpp > net.cpp.2 && mv net.cpp.2 net.cpp + sed 's/$(DEBUGFLAGS)//' -i makefile.linux-mingw make -f makefile.linux-mingw $MAKEOPTS DEPSDIR=$HOME/build bitcoin.exe USE_UPNP=1 make -f makefile.linux-mingw $MAKEOPTS DEPSDIR=$HOME/build bitcoind.exe USE_UPNP=0 i586-mingw32msvc-strip bitcoin.exe diff --git a/contrib/gitian.yml b/contrib/gitian.yml index 90be8934f..c4cdc8991 100644 --- a/contrib/gitian.yml +++ b/contrib/gitian.yml @@ -6,7 +6,7 @@ architectures: - "i386" - "amd64" packages: -- "libdb4.7++-dev" +- "libdb4.8++-dev" - "libxxf86vm-dev" - "libgtk2.0-dev" - "libboost-all-dev" @@ -17,26 +17,19 @@ remotes: - "url": "https://github.com/bitcoin/bitcoin.git" "dir": "bitcoin" files: -- "wxWidgets-2.9.1.tar.bz2" -- "miniupnpc-1.5.tar.gz" -- "toplevel.h.diff" -- "toplevel.cpp.diff" +- "wxWidgets-2.9.2.tar.bz2" +- "miniupnpc-1.6.tar.gz" script: | INSTDIR="$HOME/install" export LIBRARY_PATH="$INSTDIR/lib" # - tar xzf miniupnpc-1.5.tar.gz - cd miniupnpc-1.5 + tar xzf miniupnpc-1.6.tar.gz + cd miniupnpc-1.6 INSTALLPREFIX=$INSTDIR make $MAKEOPTS install cd .. # - tar xjf wxWidgets-2.9.1.tar.bz2 - cd wxWidgets-2.9.1 - cd include/wx/gtk - patch < ../../../../toplevel.h.diff - cd ../../../src/gtk - patch < ../../../toplevel.cpp.diff - cd ../.. + tar xjf wxWidgets-2.9.2.tar.bz2 + cd wxWidgets-2.9.2 ./configure --prefix=$INSTDIR --enable-monolithic --disable-shared perl -i -p -e "s/__TIME__/\"$REFERENCE_TIME\"/;s/__DATE__/\"$REFERENCE_DATE\"/" include/wx/chartype.h make $MAKEOPTS install @@ -50,7 +43,7 @@ script: | cp $OUTDIR/src/doc/README $OUTDIR cp $OUTDIR/src/COPYING $OUTDIR cd src - sed 's/$(DEBUGFLAGS)//' < makefile.unix > makefile.unix.2 && mv makefile.unix.2 makefile.unix + sed 's/$(DEBUGFLAGS)//' -i makefile.unix PATH=$INSTDIR/bin:$PATH make -f makefile.unix CXX="g++ -I$INSTDIR/include -L$INSTDIR/lib" $MAKEOPTS bitcoin USE_UPNP=1 PATH=$INSTDIR/bin:$PATH make -f makefile.unix CXX="g++ -I$INSTDIR/include -L$INSTDIR/lib" $MAKEOPTS bitcoind USE_UPNP=0 mkdir -p $OUTDIR/bin/$GBUILD_BITS diff --git a/contrib/wx-patches/README b/contrib/wx-patches/README deleted file mode 100644 index 2afb4a9e9..000000000 --- a/contrib/wx-patches/README +++ /dev/null @@ -1,4 +0,0 @@ -This folder contains two patches which are applied to wxWidgets -2.9.1 before building the wxWidgets which is used for release -versions of bitcoin. They make the GUI show up on newer OSs -with new libgtks, such as Ubuntu 11.04. diff --git a/contrib/wx-patches/toplevel.cpp.diff b/contrib/wx-patches/toplevel.cpp.diff deleted file mode 100644 index 359abf28d..000000000 --- a/contrib/wx-patches/toplevel.cpp.diff +++ /dev/null @@ -1,86 +0,0 @@ ---- /wxWidgets/trunk/src/gtk/toplevel.cpp (revision 67326) -+++ /wxWidgets/trunk/src/gtk/toplevel.cpp (revision 67496) -@@ -72,4 +72,8 @@ - // send any activate events at all - static int g_sendActivateEvent = -1; -+ -+// Whether _NET_REQUEST_FRAME_EXTENTS support is working -+// 0 == not tested yet, 1 == working, 2 == broken -+static int gs_requestFrameExtentsStatus; - - //----------------------------------------------------------------------------- -@@ -432,4 +436,12 @@ - if (event->state == GDK_PROPERTY_NEW_VALUE && event->atom == property) - { -+ if (win->m_netFrameExtentsTimerId) -+ { -+ // WM support for _NET_REQUEST_FRAME_EXTENTS is working -+ gs_requestFrameExtentsStatus = 1; -+ g_source_remove(win->m_netFrameExtentsTimerId); -+ win->m_netFrameExtentsTimerId = 0; -+ } -+ - wxSize decorSize = win->m_decorSize; - int left, right, top, bottom; -@@ -439,4 +451,22 @@ - win->GTKUpdateDecorSize(decorSize); - } -+ return false; -+} -+} -+ -+extern "C" { -+static gboolean request_frame_extents_timeout(void* data) -+{ -+ // WM support for _NET_REQUEST_FRAME_EXTENTS is broken -+ gs_requestFrameExtentsStatus = 2; -+ gdk_threads_enter(); -+ wxTopLevelWindowGTK* win = static_cast(data); -+ win->m_netFrameExtentsTimerId = 0; -+ wxSize decorSize = win->m_decorSize; -+ int left, right, top, bottom; -+ if (wxGetFrameExtents(gtk_widget_get_window(win->m_widget), &left, &right, &top, &bottom)) -+ decorSize.Set(left + right, top + bottom); -+ win->GTKUpdateDecorSize(decorSize); -+ gdk_threads_leave(); - return false; - } -@@ -459,4 +489,5 @@ - m_deferShowAllowed = true; - m_updateDecorSize = true; -+ m_netFrameExtentsTimerId = 0; - - m_urgency_hint = -2; -@@ -811,5 +842,6 @@ - if (deferShow) - { -- deferShow = m_deferShowAllowed && !GTK_WIDGET_REALIZED(m_widget); -+ deferShow = gs_requestFrameExtentsStatus != 2 && -+ m_deferShowAllowed && !gtk_widget_get_realized(m_widget); - if (deferShow) - { -@@ -829,11 +861,4 @@ - // GetSize()/SetSize() because it makes window bigger between each - // restore and save. -- m_updateDecorSize = deferShow; -- } -- if (deferShow) -- { -- // Fluxbox support for _NET_REQUEST_FRAME_EXTENTS is broken -- const char* name = gdk_x11_screen_get_window_manager_name(screen); -- deferShow = strcmp(name, "Fluxbox") != 0; - m_updateDecorSize = deferShow; - } -@@ -875,4 +900,12 @@ - (XEvent*)&xevent); - -+ if (gs_requestFrameExtentsStatus == 0) -+ { -+ // if WM does not respond to request within 1 second, -+ // we assume support for _NET_REQUEST_FRAME_EXTENTS is not working -+ m_netFrameExtentsTimerId = -+ g_timeout_add(1000, request_frame_extents_timeout, this); -+ } -+ - // defer calling gtk_widget_show() - m_isShown = true; diff --git a/contrib/wx-patches/toplevel.h.diff b/contrib/wx-patches/toplevel.h.diff deleted file mode 100644 index c2718d463..000000000 --- a/contrib/wx-patches/toplevel.h.diff +++ /dev/null @@ -1,9 +0,0 @@ ---- /wxWidgets/trunk/include/wx/gtk/toplevel.h (revision 65373) -+++ /wxWidgets/trunk/include/wx/gtk/toplevel.h (revision 67496) -@@ -114,4 +114,6 @@ - // wxUSER_ATTENTION_ERROR difference, -2 for no hint, -1 for ERROR hint, rest for GtkTimeout handle. - int m_urgency_hint; -+ // timer for detecting WM with broken _NET_REQUEST_FRAME_EXTENTS handling -+ unsigned m_netFrameExtentsTimerId; - - // return the size of the window without WM decorations diff --git a/doc/build-msw.txt b/doc/build-msw.txt index 1911008d1..d08e3a23b 100644 --- a/doc/build-msw.txt +++ b/doc/build-msw.txt @@ -27,11 +27,11 @@ Dependencies Libraries you need to download separately and build: default path download -wxWidgets \wxwidgets-2.9.1-mgw http://www.wxwidgets.org/downloads/ +wxWidgets \wxwidgets-2.9.2-mgw http://www.wxwidgets.org/downloads/ OpenSSL \openssl-1.0.0d-mgw http://www.openssl.org/source/ -Berkeley DB \db-4.7.25.NC-mgw http://www.oracle.com/technology/software/products/berkeley-db/index.html -Boost \boost-1.43.0-mgw http://www.boost.org/users/download/ -miniupnpc \upnpc-exe-win32-20110215 http://miniupnp.tuxfamily.org/files/ +Berkeley DB \db-4.8.30.NC-mgw http://www.oracle.com/technology/software/products/berkeley-db/index.html +Boost \boost-1.47.0-mgw http://www.boost.org/users/download/ +miniupnpc \miniupnpc-1.6-mgw http://miniupnp.tuxfamily.org/files/ Their licenses: wxWidgets LGPL 2.1 with very liberal exceptions @@ -41,11 +41,11 @@ Boost MIT-like license miniupnpc New (3-clause) BSD license Versions used in this release: -wxWidgets 2.9.1 +wxWidgets 2.9.2 OpenSSL 1.0.0d -Berkeley DB 4.7.25.NC -Boost 1.43.0 -miniupnpc 1.5-20110215 +Berkeley DB 4.8.30.NC +Boost 1.47.0 +miniupnpc 1.6 Notes @@ -57,7 +57,7 @@ classes that do the rote work of constructing all the UI elements. wxWidgets --------- DOS shell: -cd \wxWidgets-2.9.1-mgw\build\msw +cd \wxWidgets-2.9.2-mgw\build\msw mingw32-make -f makefile.gcc OpenSSL @@ -73,30 +73,26 @@ make Berkeley DB ----------- MSYS shell: -cd /c/db-4.7.25.NC-mgw/build_unix +cd /c/db-4.8.30.NC-mgw/build_unix sh ../dist/configure --enable-mingw --enable-cxx make - Boost ----- DOS prompt: downloaded boost jam 3.1.18 -cd \boost-1.43.0-mgw +cd \boost-1.47.0-mgw bjam toolset=gcc --build-type=complete stage -Note: -building with boost 1.45.0 failed because of boost ticket 4614, 4258 -builds fine with boost 1.43.0 - MiniUPnPc --------- -Building miniupnpc failed on Windows Server 2003, thus it is expected that a binary copy will be used. -See http://miniupnp.tuxfamily.org/forum/viewtopic.php?t=642 UPnP support is optional, make with USE_UPNP= to disable it. -Get upnpc-exe-win32-20110215.zip and unzip it to \upnpc-exe-win32-20110215 -Get miniupnpc-1.5.20110215.tar.gz and copy *.h to \upnpc-exe-win32-20110215\miniupnpc +MSYS shell: +cd /c/miniupnpc-1.6-mgw +make -f Makefile.mingw +mkdir miniupnpc +cp *.h miniupnpc/ Bitcoin ------- diff --git a/doc/build-osx.txt b/doc/build-osx.txt index ddf025003..52d876d82 100644 --- a/doc/build-osx.txt +++ b/doc/build-osx.txt @@ -135,18 +135,18 @@ The process for miniupnpc (optional) is similar to that of OpenSSL. Download from http://miniupnp.tuxfamily.org/files/. cd ~/bitcoin/deps -tar xvf ~/Downloads/miniupnpc-1.5.tar -mv miniupnpc-1.5 miniupnpc-1.5-x86_64 -tar xvf ~/Downloads/miniupnpc-1.5.tar -mv miniupnpc-1.5 miniupnpc-1.5-i386 +tar xvf ~/Downloads/miniupnpc-1.6.tar +mv miniupnpc-1.6 miniupnpc-1.6-x86_64 +tar xvf ~/Downloads/miniupnpc-1.6.tar +mv miniupnpc-1.6 miniupnpc-1.6-i386 # build x86_64 (64 bit intel) binary -cd miniupnpc-1.5-x86_64 +cd miniupnpc-1.6-x86_64 export CFLAGS="-arch x86_64" export LDFLAGS="-arch x86_64" export PREFIX="/Users/macuser/bitcoin/deps" make && make install # build i386 (32 bit intel) binary -cd miniupnpc-1.5-i386 +cd miniupnpc-1.6-i386 export CFLAGS="-arch i386" export LDFLAGS="-arch i386" export PREFIX="/Users/macuser/bitcoin/deps" @@ -154,7 +154,7 @@ make # combine the libs cd ~/bitcoin/deps -lipo -arch i386 miniupnpc-1.5-i386/libminiupnpc.a -arch x86_64 miniupnpc-1.5-x86_64/libminiupnpc.a -o lib/libminiupnpc.a -create +lipo -arch i386 miniupnpc-1.6-i386/libminiupnpc.a -arch x86_64 miniupnpc-1.6-x86_64/libminiupnpc.a -o lib/libminiupnpc.a -create Verify your binaries @@ -175,8 +175,8 @@ Berkeley DB Download from http://freshmeat.net/projects/berkeleydb/ cd ~/bitcoin/deps -tar xvf ~/Downloads/db-4.8.26.tar -cd db-4.8.26/build_unix +tar xvf ~/Downloads/db-4.8.30.tar +cd db-4.8.30/build_unix ../dist/configure --prefix=/Users/macosuser/bitcoin/deps --enable-cxx && make && make install diff --git a/doc/build-unix.txt b/doc/build-unix.txt index 0c4e88e52..8f0c568ed 100644 --- a/doc/build-unix.txt +++ b/doc/build-unix.txt @@ -25,8 +25,8 @@ Dependencies sudo apt-get install build-essential sudo apt-get install libgtk2.0-dev sudo apt-get install libssl-dev -sudo apt-get install libdb4.7-dev -sudo apt-get install libdb4.7++-dev +sudo apt-get install libdb4.8-dev +sudo apt-get install libdb4.8++-dev Boost 1.40+: sudo apt-get install libboost-all-dev or Boost 1.37: sudo apt-get install libboost1.37-dev @@ -55,10 +55,10 @@ miniupnpc New (3-clause) BSD license Versions used in this release: GCC 4.3.3 OpenSSL 0.9.8g -wxWidgets 2.9.0 -Berkeley DB 4.7.25.NC +wxWidgets 2.9.2 +Berkeley DB 4.8.30.NC Boost 1.37 -miniupnpc 1.5 +miniupnpc 1.6 Notes @@ -74,8 +74,8 @@ symbols, which reduces the executable size by about 90%. wxWidgets --------- cd /usr/local -tar -xzvf wxWidgets-2.9.0.tar.gz -cd wxWidgets-2.9.0 +tar -xzvf wxWidgets-2.9.2.tar.gz +cd wxWidgets-2.9.2 mkdir buildgtk cd buildgtk ../configure --with-gtk --enable-debug --disable-shared --enable-monolithic --without-libpng --disable-svg @@ -87,8 +87,8 @@ ldconfig miniupnpc --------- -tar -xzvf miniupnpc-1.5.tar.gz -cd miniupnpc-1.5 +tar -xzvf miniupnpc-1.6.tar.gz +cd miniupnpc-1.6 make sudo su make install @@ -96,8 +96,7 @@ make install Berkeley DB ----------- -You need Berkeley DB 4.7. Don't use 4.8, the database/log0000* files -are incompatible. If you have to build Berkeley DB yourself: +You need Berkeley DB 4.8. If you have to build Berkeley DB yourself: ../dist/configure --enable-cxx make diff --git a/src/makefile.linux-mingw b/src/makefile.linux-mingw index e2ef4213a..ddf976905 100644 --- a/src/makefile.linux-mingw +++ b/src/makefile.linux-mingw @@ -7,19 +7,19 @@ DEPSDIR:=/usr/i586-mingw32msvc USE_UPNP:=0 INCLUDEPATHS= \ - -I"$(DEPSDIR)/boost_1_43_0" \ - -I"$(DEPSDIR)/db-4.7.25.NC/build_unix" \ + -I"$(DEPSDIR)/boost_1_47_0" \ + -I"$(DEPSDIR)/db-4.8.30.NC/build_unix" \ -I"$(DEPSDIR)/openssl-1.0.0d/include" \ - -I"$(DEPSDIR)/wxWidgets-2.9.1/lib/gcc_lib/mswud" \ - -I"$(DEPSDIR)/wxWidgets-2.9.1/include" \ - -I"$(DEPSDIR)/wxWidgets-2.9.1/lib/wx/include/i586-mingw32msvc-msw-unicode-static-2.9/" \ + -I"$(DEPSDIR)/wxWidgets-2.9.2/lib/gcc_lib/mswud" \ + -I"$(DEPSDIR)/wxWidgets-2.9.2/include" \ + -I"$(DEPSDIR)/wxWidgets-2.9.2/lib/wx/include/i586-mingw32msvc-msw-unicode-static-2.9/" \ -I"$(DEPSDIR)" LIBPATHS= \ - -L"$(DEPSDIR)/boost_1_43_0/stage/lib" \ - -L"$(DEPSDIR)/db-4.7.25.NC/build_unix" \ + -L"$(DEPSDIR)/boost_1_47_0/stage/lib" \ + -L"$(DEPSDIR)/db-4.8.30.NC/build_unix" \ -L"$(DEPSDIR)/openssl-1.0.0d" \ - -L"$(DEPSDIR)/wxWidgets-2.9.1/lib" + -L"$(DEPSDIR)/wxWidgets-2.9.2/lib" WXLIBS= -l wx_mswu-2.9-i586-mingw32msvc @@ -32,7 +32,7 @@ LIBS= \ -l ssl \ -l crypto -DEFS=-D_MT -DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH -DUSE_SSL +DEFS=-D_MT -DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH -DUSE_SSL -DBOOST_THREAD_USE_LIB DEBUGFLAGS=-g -D__WXDEBUG__ CFLAGS=-O2 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \ @@ -40,8 +40,7 @@ HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h crypter.h init.h ifdef USE_UPNP - INCLUDEPATHS += -I"$(DEPSDIR)/upnpc-exe-win32-20110215" - LIBPATHS += -L"$(DEPSDIR)/upnpc-exe-win32-20110215" + LIBPATHS += -L"$(DEPSDIR)/miniupnpc" LIBS += -l miniupnpc -l iphlpapi DEFS += -DSTATICLIB -DUSE_UPNP=$(USE_UPNP) endif diff --git a/src/makefile.mingw b/src/makefile.mingw index 96f81b306..a6654f30a 100644 --- a/src/makefile.mingw +++ b/src/makefile.mingw @@ -5,31 +5,31 @@ USE_UPNP:=0 INCLUDEPATHS= \ - -I"C:\boost-1.43.0-mgw" \ - -I"C:\db-4.7.25.NC-mgw\build_unix" \ + -I"C:\boost-1.47.0-mgw" \ + -I"C:\db-4.8.30.NC-mgw\build_unix" \ -I"C:\openssl-1.0.0d-mgw\include" \ - -I"C:\wxWidgets-2.9.1-mgw\lib\gcc_lib\mswud" \ - -I"C:\wxWidgets-2.9.1-mgw\include" + -I"C:\wxWidgets-2.9.2-mgw\lib\gcc_lib\mswud" \ + -I"C:\wxWidgets-2.9.2-mgw\include" LIBPATHS= \ - -L"C:\boost-1.43.0-mgw\stage\lib" \ - -L"C:\db-4.7.25.NC-mgw\build_unix" \ + -L"C:\boost-1.47.0-mgw\stage\lib" \ + -L"C:\db-4.8.30.NC-mgw\build_unix" \ -L"C:\openssl-1.0.0d-mgw" \ - -L"C:\wxWidgets-2.9.1-mgw\lib\gcc_lib" + -L"C:\wxWidgets-2.9.2-mgw\lib\gcc_lib" WXLIBS= \ -l wxmsw29ud_html -l wxmsw29ud_core -l wxmsw29ud_adv -l wxbase29ud -l wxtiffd -l wxjpegd -l wxpngd -l wxzlibd LIBS= \ - -l boost_system-mgw45-mt-s-1_43 \ - -l boost_filesystem-mgw45-mt-s-1_43 \ - -l boost_program_options-mgw45-mt-s-1_43 \ - -l boost_thread-mgw45-mt-s-1_43 \ + -l boost_system-mgw45-mt-s-1_47 \ + -l boost_filesystem-mgw45-mt-s-1_47 \ + -l boost_program_options-mgw45-mt-s-1_47 \ + -l boost_thread-mgw45-mt-s-1_47 \ -l db_cxx \ -l ssl \ -l crypto -DEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH -DUSE_SSL +DEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH -DUSE_SSL -DBOOST_THREAD_USE_LIB DEBUGFLAGS=-g -D__WXDEBUG__ CFLAGS=-mthreads -O2 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \ @@ -37,8 +37,8 @@ HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h init.h crypter.h ifdef USE_UPNP - INCLUDEPATHS += -I"C:\upnpc-exe-win32-20110215" - LIBPATHS += -L"C:\upnpc-exe-win32-20110215" + INCLUDEPATHS += -I"C:\miniupnpc-1.6-mgw" + LIBPATHS += -L"C:\miniupnpc-1.6-mgw" LIBS += -l miniupnpc -l iphlpapi DEFS += -DSTATICLIB -DUSE_UPNP=$(USE_UPNP) endif diff --git a/src/net.cpp b/src/net.cpp index 3953f021e..c498c4010 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -12,11 +12,6 @@ #ifdef __WXMSW__ #include -// This file can be downloaded as a part of the Windows Platform SDK -// and is required for Bitcoin binaries to work properly on versions -// of Windows before XP. If you are doing builds of Bitcoin for -// public release, you should uncomment this line. -//#include #endif #ifdef USE_UPNP @@ -1079,10 +1074,11 @@ void ThreadMapPort2(void* parg) const char * rootdescurl = 0; const char * multicastif = 0; const char * minissdpdpath = 0; + int error = 0; struct UPNPDev * devlist = 0; char lanaddr[64]; - devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0); + devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error); struct UPNPUrls urls; struct IGDdatas data; @@ -1094,14 +1090,9 @@ void ThreadMapPort2(void* parg) char intClient[16]; char intPort[6]; string strDesc = "Bitcoin " + FormatFullVersion(); - -#ifndef __WXMSW__ - r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, - port, port, lanaddr, strDesc.c_str(), "TCP", 0); -#else r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0"); -#endif + if(r!=UPNPCOMMAND_SUCCESS) printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", port, port, lanaddr, r, strupnperror(r)); From d2cbb14d7c7258e08cd5e67d64bf163a68e1a8d8 Mon Sep 17 00:00:00 2001 From: Dev Random Date: Tue, 23 Aug 2011 08:33:53 -0400 Subject: [PATCH 13/29] Linux gitian config with separate wxWidgets build --- contrib/gitian.yml | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/contrib/gitian.yml b/contrib/gitian.yml index c4cdc8991..9f03ba1bc 100644 --- a/contrib/gitian.yml +++ b/contrib/gitian.yml @@ -12,12 +12,13 @@ packages: - "libboost-all-dev" - "libssl-dev" - "git-core" +- "unzip" reference_datetime: "2011-01-30 00:00:00" remotes: - "url": "https://github.com/bitcoin/bitcoin.git" "dir": "bitcoin" files: -- "wxWidgets-2.9.2.tar.bz2" +- "wxWidgets-2.9.2-gitian.zip" - "miniupnpc-1.6.tar.gz" script: | INSTDIR="$HOME/install" @@ -28,11 +29,17 @@ script: | INSTALLPREFIX=$INSTDIR make $MAKEOPTS install cd .. # - tar xjf wxWidgets-2.9.2.tar.bz2 + mkdir -p $INSTDIR/bin $INSTDIR/lib/wx $INSTDIR/include + mkdir wxWidgets-2.9.2 cd wxWidgets-2.9.2 - ./configure --prefix=$INSTDIR --enable-monolithic --disable-shared - perl -i -p -e "s/__TIME__/\"$REFERENCE_TIME\"/;s/__DATE__/\"$REFERENCE_DATE\"/" include/wx/chartype.h - make $MAKEOPTS install + unzip ../wxWidgets-2.9.2-gitian.zip + cp -a bin/$GBUILD_BITS/wx/config/gtk2-unicode-static-2.9 $INSTDIR/bin/wx-config + for lib in wx_gtk2u wxregexu wxtiff; do + ar rc $INSTDIR/lib/lib${lib}-2.9.a bin/$GBUILD_BITS/$lib/*.o + ranlib $INSTDIR/lib/lib${lib}-2.9.a + done + cp -a include/wx-2.9/* $INSTDIR/include + cp -a bin/$GBUILD_BITS/wx/include $INSTDIR/lib/wx cd .. # cd bitcoin From bef41ada0d708053a80c4a141221c8f6efbd1626 Mon Sep 17 00:00:00 2001 From: Dev Random Date: Tue, 23 Aug 2011 08:42:11 -0400 Subject: [PATCH 14/29] Mingw gitian with separate wxWidgets and boost --- contrib/gitian-win32.yml | 43 ++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/contrib/gitian-win32.yml b/contrib/gitian-win32.yml index d4b0843e7..9dce28fba 100644 --- a/contrib/gitian-win32.yml +++ b/contrib/gitian-win32.yml @@ -14,18 +14,38 @@ remotes: - "url": "https://github.com/bitcoin/bitcoin.git" "dir": "bitcoin" files: -- "wxWidgets-2.9.2.tar.bz2" -- "boost_1_47_0.tar.bz2" +- "wxwidgets-win32-2.9.2-gitian.zip" +- "boost-win32-1.47.0-gitian.zip" - "openssl-1.0.0d.tar.gz" - "db-4.8.30.NC.tar.gz" - "miniupnpc-1.6.tar.gz" script: | # - tar xjf wxWidgets-2.9.2.tar.bz2 + mkdir wxWidgets-2.9.2 cd wxWidgets-2.9.2 - ./configure --host=i586-mingw32msvc --build=i686-linux --disable-shared --enable-monolithic --without-libpng --disable-svg - perl -i -p -e "s/__TIME__/\"$REFERENCE_TIME\"/;s/__DATE__/\"$REFERENCE_DATE\"/" include/wx/chartype.h - make $MAKEOPTS + mkdir lib + unzip ../wxwidgets-win32-2.9.2-gitian.zip + cd bin/$GBUILD_BITS + for lib in wx_mswu; do + i586-mingw32msvc-ar rc ../../lib/lib${lib}-2.9-i586-mingw32msvc.a $lib/*.o + i586-mingw32msvc-ranlib ../../lib/lib${lib}-2.9-i586-mingw32msvc.a + done + cp -a wx ../../lib + cd ../.. + mv include/wx-2.9/wx include + cd .. + # + mkdir boost_1_47_0 + cd boost_1_47_0 + mkdir -p stage/lib + unzip ../boost-win32-1.47.0-gitian.zip + cd bin/$GBUILD_BITS + for lib in *; do + i586-mingw32msvc-ar rc ../../stage/lib/libboost_${lib}-mt-s.a $lib/*.o + i586-mingw32msvc-ranlib ../../stage/lib/libboost_${lib}-mt-s.a + done + cd ../.. + mv include/boost . cd .. # tar xzf openssl-1.0.0d.tar.gz @@ -40,17 +60,6 @@ script: | make $MAKEOPTS cd ../.. # - tar xjf boost_1_47_0.tar.bz2 - cd boost_1_47_0 - echo "using gcc : 4.4 : i586-mingw32msvc-g++ - : - i586-mingw32msvc-windres - i586-mingw32msvc-ar - ;" > user-config.jam - ./bootstrap.sh --without-icu - ./bjam toolset=gcc target-os=windows threadapi=win32 threading=multi --user-config=user-config.jam --without-mpi --without-python -sNO_BZIP2=1 -sNO_ZLIB=1 --layout=tagged --build-type=complete $MAKEOPTS stage - cd .. - # tar xzf miniupnpc-1.6.tar.gz cd miniupnpc-1.6 sed 's/dllwrap -k --driver-name gcc/$(DLLWRAP) -k --driver-name $(CC)/' -i Makefile.mingw From 3bb23e5c8b0d760f587a6a97089b50e9d45b9a95 Mon Sep 17 00:00:00 2001 From: Dev Random Date: Tue, 23 Aug 2011 08:43:24 -0400 Subject: [PATCH 15/29] Mingw gitian build with deterministic bitcoin.exe by use of faketime --- contrib/gitian-win32.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/contrib/gitian-win32.yml b/contrib/gitian-win32.yml index 9dce28fba..963c38139 100644 --- a/contrib/gitian-win32.yml +++ b/contrib/gitian-win32.yml @@ -9,6 +9,7 @@ packages: - "git-core" - "unzip" - "nsis" +- "faketime" reference_datetime: "2011-01-30 00:00:00" remotes: - "url": "https://github.com/bitcoin/bitcoin.git" @@ -76,7 +77,10 @@ script: | cp $OUTDIR/src/doc/README_windows.txt $OUTDIR/readme.txt cp $OUTDIR/src/COPYING $OUTDIR/license.txt cd src - sed 's/$(DEBUGFLAGS)//' -i makefile.linux-mingw + sed 's/$(DEBUGFLAGS)/-frandom-seed=bitcoin/' -i makefile.linux-mingw + export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 + export FAKETIME=$REFERENCE_DATETIME + export TZ=UTC make -f makefile.linux-mingw $MAKEOPTS DEPSDIR=$HOME/build bitcoin.exe USE_UPNP=1 make -f makefile.linux-mingw $MAKEOPTS DEPSDIR=$HOME/build bitcoind.exe USE_UPNP=0 i586-mingw32msvc-strip bitcoin.exe From e40bef3c0a1a208f795c1e265d6e8a7244afe5f6 Mon Sep 17 00:00:00 2001 From: Dev Random Date: Tue, 23 Aug 2011 12:46:45 -0400 Subject: [PATCH 16/29] Add Gitian Build descriptors for Boost and wxWidgets. --- contrib/boost-win32.yml | 38 +++++++++++++++++++++++++++++++++ contrib/wxwidgets-win32.yml | 40 +++++++++++++++++++++++++++++++++++ contrib/wxwidgets.yml | 42 +++++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 contrib/boost-win32.yml create mode 100644 contrib/wxwidgets-win32.yml create mode 100644 contrib/wxwidgets.yml diff --git a/contrib/boost-win32.yml b/contrib/boost-win32.yml new file mode 100644 index 000000000..61ea50e4f --- /dev/null +++ b/contrib/boost-win32.yml @@ -0,0 +1,38 @@ +--- +name: "boost" +suites: +- "lucid" +architectures: +- "i386" +packages: +- "mingw32" +- "faketime" +- "zip" +reference_datetime: "2011-01-30 00:00:00" +remotes: [] +files: +- "boost_1_47_0.tar.bz2" +script: | + TMPDIR="$HOME/tmpdir" + mkdir -p $TMPDIR/bin/$GBUILD_BITS $TMPDIR/include + tar xjf boost_1_47_0.tar.bz2 + cd boost_1_47_0 + echo "using gcc : 4.4 : i586-mingw32msvc-g++ + : + i586-mingw32msvc-windres + i586-mingw32msvc-ar + -frandom-seed=boost1 + ;" > user-config.jam + ./bootstrap.sh --without-icu + ./bjam toolset=gcc target-os=windows threadapi=win32 threading=multi variant=release link=static --user-config=user-config.jam --without-mpi --without-python -sNO_BZIP2=1 -sNO_ZLIB=1 --layout=tagged --build-type=complete $MAKEOPTS stage + for lib in chrono date_time exception filesystem graph iostreams math_c99f math_c99l math_c99 math_tr1f math_tr1l math_tr1 prg_exec_monitor program_options random regex serialization signals system test_exec_monitor thread_win32 unit_test_framework wave wserialization; do + mkdir $lib + (cd $lib ; ar xf ../stage/lib/libboost_${lib}-mt-s.a) + mv $lib $TMPDIR/bin/$GBUILD_BITS + done + cp -a boost $TMPDIR/include + cd $TMPDIR + export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 + export FAKETIME=$REFERENCE_DATETIME + zip -r boost-win32-1.47.0-gitian.zip * + cp boost-win32-1.47.0-gitian.zip $OUTDIR diff --git a/contrib/wxwidgets-win32.yml b/contrib/wxwidgets-win32.yml new file mode 100644 index 000000000..3d49d7b35 --- /dev/null +++ b/contrib/wxwidgets-win32.yml @@ -0,0 +1,40 @@ +--- +name: "wxwidgets" +suites: +- "lucid" +architectures: +- "i386" +packages: +- "mingw32" +- "faketime" +- "zip" +reference_datetime: "2011-01-30 00:00:00" +remotes: [] +files: +- "wxWidgets-2.9.2.tar.bz2" +script: | + INSTDIR="$HOME/install" + TMPDIR="$HOME/tmpdir" + export LIBRARY_PATH="$INSTDIR/lib" + # + tar xjf wxWidgets-2.9.2.tar.bz2 + cd wxWidgets-2.9.2 + CXXFLAGS=-frandom-seed=wx1 ./configure --host=i586-mingw32msvc --build=i686-linux --prefix=$INSTDIR --disable-shared --enable-monolithic --without-libpng --disable-svg + perl -i -p -e "s/__TIME__/\"$REFERENCE_TIME\"/;s/__DATE__/\"$REFERENCE_DATE\"/" include/wx/chartype.h + make $MAKEOPTS install + mkdir $TMPDIR + cd $TMPDIR + cp -af $INSTDIR/include . + mkdir -p $TMPDIR/bin/$GBUILD_BITS + cd $TMPDIR/bin/$GBUILD_BITS + cp -af $INSTDIR/lib/wx . + for lib in wx_mswu; do + mkdir $lib + (cd $lib ; ar xf $INSTDIR/lib/lib${lib}-2.9-i586-mingw32msvc.a) + done + chmod -R +w $TMPDIR + cd $TMPDIR + export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 + export FAKETIME=$REFERENCE_DATETIME + zip -r wxwidgets-win32-2.9.2-gitian.zip * + cp wxwidgets-win32-2.9.2-gitian.zip $OUTDIR diff --git a/contrib/wxwidgets.yml b/contrib/wxwidgets.yml new file mode 100644 index 000000000..a2406936d --- /dev/null +++ b/contrib/wxwidgets.yml @@ -0,0 +1,42 @@ +--- +name: "wxwidgets" +suites: +- "lucid" +architectures: +- "i386" +- "amd64" +packages: +- "libxxf86vm-dev" +- "libgtk2.0-dev" +- "faketime" +- "zip" +reference_datetime: "2011-01-30 00:00:00" +remotes: [] +files: +- "wxWidgets-2.9.2.tar.bz2" +script: | + INSTDIR="$HOME/install" + TMPDIR="$HOME/tmpdir" + export LIBRARY_PATH="$INSTDIR/lib" + # + tar xjf wxWidgets-2.9.2.tar.bz2 + cd wxWidgets-2.9.2 + ./configure --prefix=$INSTDIR --enable-monolithic --disable-shared + perl -i -p -e "s/__TIME__/\"$REFERENCE_TIME\"/;s/__DATE__/\"$REFERENCE_DATE\"/" include/wx/chartype.h + make $MAKEOPTS install + mkdir $TMPDIR + cd $TMPDIR + cp -af $INSTDIR/include . + mkdir -p $TMPDIR/bin/$GBUILD_BITS + cd $TMPDIR/bin/$GBUILD_BITS + cp -af $INSTDIR/lib/wx . + for lib in wxtiff wxregexu wx_gtk2u; do + mkdir $lib + (cd $lib ; ar xf $INSTDIR/lib/lib${lib}-2.9.a) + done + chmod -R +w $TMPDIR + cd $TMPDIR + export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 + export FAKETIME=$REFERENCE_DATETIME + zip -r wxWidgets-2.9.2-gitian.zip * + cp wxWidgets-2.9.2-gitian.zip $OUTDIR From 927aaa0f27463885ca97c76856044d948d4c36bb Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Wed, 31 Aug 2011 12:27:41 -0400 Subject: [PATCH 17/29] Add reference python miner, in contrib/pyminer/ --- contrib/pyminer/README | 6 + contrib/pyminer/example-config.cfg | 32 ++++ contrib/pyminer/pyminer.py | 252 +++++++++++++++++++++++++++++ 3 files changed, 290 insertions(+) create mode 100644 contrib/pyminer/README create mode 100644 contrib/pyminer/example-config.cfg create mode 100755 contrib/pyminer/pyminer.py diff --git a/contrib/pyminer/README b/contrib/pyminer/README new file mode 100644 index 000000000..d1596575d --- /dev/null +++ b/contrib/pyminer/README @@ -0,0 +1,6 @@ + +This is a 'getwork' CPU mining client for bitcoin. + +It is pure-python, and therefore very, very slow. The purpose is to +provide a reference implementation of a miner, for study. + diff --git a/contrib/pyminer/example-config.cfg b/contrib/pyminer/example-config.cfg new file mode 100644 index 000000000..103e7c137 --- /dev/null +++ b/contrib/pyminer/example-config.cfg @@ -0,0 +1,32 @@ + +# +# RPC login details +# +host=127.0.0.1 +port=8332 + +rpcuser=myusername +rpcpass=mypass + + +# +# mining details +# + +threads=4 + +# periodic rate for requesting new work, if solution not found +scantime=60 + + +# +# misc. +# + +# not really used right now +logdir=/tmp/pyminer + +# set to 1, to enable hashmeter output +hashmeter=0 + + diff --git a/contrib/pyminer/pyminer.py b/contrib/pyminer/pyminer.py new file mode 100755 index 000000000..2887aba59 --- /dev/null +++ b/contrib/pyminer/pyminer.py @@ -0,0 +1,252 @@ +#!/usr/bin/python +# +# Copyright (c) 2011 The Bitcoin developers +# Distributed under the MIT/X11 software license, see the accompanying +# file license.txt or http://www.opensource.org/licenses/mit-license.php. +# + +import time +import json +import pprint +import hashlib +import struct +import re +import base64 +import httplib +import sys +from multiprocessing import Process + +ERR_SLEEP = 15 +MAX_NONCE = 1000000L + +settings = {} +pp = pprint.PrettyPrinter(indent=4) + +class BitcoinRPC: + OBJID = 1 + + def __init__(self, host, port, username, password): + authpair = "%s:%s" % (username, password) + self.authhdr = "Basic %s" % (base64.b64encode(authpair)) + self.conn = httplib.HTTPConnection(host, port, False, 30) + def rpc(self, method, params=None): + self.OBJID += 1 + obj = { 'version' : '1.1', + 'method' : method, + 'id' : self.OBJID } + if params is None: + obj['params'] = [] + else: + obj['params'] = params + self.conn.request('POST', '/', json.dumps(obj), + { 'Authorization' : self.authhdr, + 'Content-type' : 'application/json' }) + + resp = self.conn.getresponse() + if resp is None: + print "JSON-RPC: no response" + return None + + body = resp.read() + resp_obj = json.loads(body) + if resp_obj is None: + print "JSON-RPC: cannot JSON-decode body" + return None + if 'error' in resp_obj and resp_obj['error'] != None: + return resp_obj['error'] + if 'result' not in resp_obj: + print "JSON-RPC: no result in object" + return None + + return resp_obj['result'] + def getblockcount(self): + return self.rpc('getblockcount') + def getwork(self, data=None): + return self.rpc('getwork', data) + +def uint32(x): + return x & 0xffffffffL + +def bytereverse(x): + return uint32(( ((x) << 24) | (((x) << 8) & 0x00ff0000) | + (((x) >> 8) & 0x0000ff00) | ((x) >> 24) )) + +def bufreverse(in_buf): + out_words = [] + for i in range(0, len(in_buf), 4): + word = struct.unpack('@I', in_buf[i:i+4])[0] + out_words.append(struct.pack('@I', bytereverse(word))) + return ''.join(out_words) + +def wordreverse(in_buf): + out_words = [] + for i in range(0, len(in_buf), 4): + out_words.append(in_buf[i:i+4]) + out_words.reverse() + return ''.join(out_words) + +class Miner: + def __init__(self, id): + self.id = id + self.max_nonce = MAX_NONCE + + def work(self, datastr, targetstr): + # decode work data hex string to binary + static_data = datastr.decode('hex') + static_data = bufreverse(static_data) + + # the first 76b of 80b do not change + blk_hdr = static_data[:76] + + # decode 256-bit target value + targetbin = targetstr.decode('hex') + targetbin = targetbin[::-1] # byte-swap and dword-swap + targetbin_str = targetbin.encode('hex') + target = long(targetbin_str, 16) + + # pre-hash first 76b of block header + static_hash = hashlib.sha256() + static_hash.update(blk_hdr) + + for nonce in xrange(self.max_nonce): + + # encode 32-bit nonce value + nonce_bin = struct.pack(" Upstream RPC result:", result + + def iterate(self, rpc): + work = rpc.getwork() + if work is None: + time.sleep(ERR_SLEEP) + return + if 'data' not in work or 'target' not in work: + time.sleep(ERR_SLEEP) + return + + time_start = time.time() + + (hashes_done, nonce_bin) = self.work(work['data'], + work['target']) + + time_end = time.time() + time_diff = time_end - time_start + + self.max_nonce = long( + (hashes_done * settings['scantime']) / time_diff) + if self.max_nonce > 0xfffffffaL: + self.max_nonce = 0xfffffffaL + + if settings['hashmeter']: + print "HashMeter(%d): %d hashes, %.2f Khash/sec" % ( + self.id, hashes_done, + (hashes_done / 1000.0) / time_diff) + + if nonce_bin is not None: + self.submit_work(rpc, work['data'], nonce_bin) + + def loop(self): + rpc = BitcoinRPC(settings['host'], settings['port'], + settings['rpcuser'], settings['rpcpass']) + if rpc is None: + return + + while True: + self.iterate(rpc) + +def miner_thread(id): + miner = Miner(id) + miner.loop() + +if __name__ == '__main__': + if len(sys.argv) != 2: + print "Usage: pyminer.py CONFIG-FILE" + sys.exit(1) + + f = open(sys.argv[1]) + for line in f: + # skip comment lines + m = re.search('^\s*#', line) + if m: + continue + + # parse key=value lines + m = re.search('^(\w+)\s*=\s*(\S.*)$', line) + if m is None: + continue + settings[m.group(1)] = m.group(2) + f.close() + + if 'host' not in settings: + settings['host'] = '127.0.0.1' + if 'port' not in settings: + settings['port'] = 8332 + if 'threads' not in settings: + settings['threads'] = 1 + if 'hashmeter' not in settings: + settings['hashmeter'] = 0 + if 'scantime' not in settings: + settings['scantime'] = 30L + if 'rpcuser' not in settings or 'rpcpass' not in settings: + print "Missing username and/or password in cfg file" + sys.exit(1) + + settings['port'] = int(settings['port']) + settings['threads'] = int(settings['threads']) + settings['hashmeter'] = int(settings['hashmeter']) + settings['scantime'] = long(settings['scantime']) + + thr_list = [] + for thr_id in range(settings['threads']): + p = Process(target=miner_thread, args=(thr_id,)) + p.start() + thr_list.append(p) + time.sleep(1) # stagger threads + + print settings['threads'], "mining threads started" + + print time.asctime(), "Miner Starts - %s:%s" % (settings['host'], settings['port']) + try: + for thr_proc in thr_list: + thr_proc.join() + except KeyboardInterrupt: + pass + print time.asctime(), "Miner Stops - %s:%s" % (settings['host'], settings['port']) + From b0243da77c6ee8d8ca59b4423f333a179bff02cf Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Mon, 29 Aug 2011 17:03:08 -0400 Subject: [PATCH 18/29] Highlight mis-matching locks --- src/util.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/util.cpp b/src/util.cpp index 24c7ed448..390b3a340 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -942,17 +942,21 @@ static std::map, LockStack> lock static boost::thread_specific_ptr lockstack; -static void potential_deadlock_detected(const LockStack& s1, const LockStack& s2) +static void potential_deadlock_detected(const std::pair& mismatch, const LockStack& s1, const LockStack& s2) { printf("POTENTIAL DEADLOCK DETECTED\n"); printf("Previous lock order was:\n"); BOOST_FOREACH(const PAIRTYPE(CCriticalSection*, CLockLocation)& i, s2) { + if (i.first == mismatch.first) printf(" (1)"); + if (i.first == mismatch.second) printf(" (2)"); printf(" %s %s:%d\n", i.second.mutexName.c_str(), i.second.sourceFile.c_str(), i.second.sourceLine); } printf("Current lock order is:\n"); BOOST_FOREACH(const PAIRTYPE(CCriticalSection*, CLockLocation)& i, s1) { + if (i.first == mismatch.first) printf(" (1)"); + if (i.first == mismatch.second) printf(" (2)"); printf(" %s %s:%d\n", i.second.mutexName.c_str(), i.second.sourceFile.c_str(), i.second.sourceLine); } } @@ -979,7 +983,7 @@ static void push_lock(CCriticalSection* c, const CLockLocation& locklocation) std::pair p2 = std::make_pair(c, i.first); if (lockorders.count(p2)) { - potential_deadlock_detected(lockorders[p2], lockorders[p1]); + potential_deadlock_detected(p1, lockorders[p2], lockorders[p1]); break; } } From 6cc4a62c0e696dcb9d90ba0504f688e4f644a10f Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Fri, 26 Aug 2011 14:37:23 -0400 Subject: [PATCH 19/29] Fix rpc-hanging deadlocks Collapsed multiple wallet mutexes to a single cs_wallet, to avoid deadlocks with wallet methods that acquired locks in different order. Also change master RPC call handler to acquire cs_main and cs_wallet locks before executing RPC calls; requiring each RPC call to acquire the right set of locks in the right order was too error-prone. --- src/db.cpp | 3 +- src/keystore.cpp | 8 +- src/keystore.h | 44 ++-- src/main.cpp | 2 +- src/rpc.cpp | 633 +++++++++++++++++++++-------------------------- src/script.cpp | 102 ++++---- src/ui.cpp | 17 +- src/wallet.cpp | 209 ++++++++-------- src/wallet.h | 15 +- 9 files changed, 472 insertions(+), 561 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index 72542705a..a22b17e34 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -683,8 +683,7 @@ int CWalletDB::LoadWallet(CWallet* pwallet) #endif //// todo: shouldn't we catch exceptions and try to recover and continue? - CRITICAL_BLOCK(pwallet->cs_mapWallet) - CRITICAL_BLOCK(pwallet->cs_KeyStore) + CRITICAL_BLOCK(pwallet->cs_wallet) { // Get cursor Dbc* pcursor = GetCursor(); diff --git a/src/keystore.cpp b/src/keystore.cpp index 4c6848b47..5bf919cb8 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -45,7 +45,7 @@ std::vector CCryptoKeyStore::GenerateNewKey() bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn) { - CRITICAL_BLOCK(cs_vMasterKey) + CRITICAL_BLOCK(cs_KeyStore) { if (!SetCrypted()) return false; @@ -72,7 +72,6 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn) bool CCryptoKeyStore::AddKey(const CKey& key) { CRITICAL_BLOCK(cs_KeyStore) - CRITICAL_BLOCK(cs_vMasterKey) { if (!IsCrypted()) return CBasicKeyStore::AddKey(key); @@ -106,7 +105,7 @@ bool CCryptoKeyStore::AddCryptedKey(const std::vector &vchPubKey, bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const { - CRITICAL_BLOCK(cs_vMasterKey) + CRITICAL_BLOCK(cs_KeyStore) { if (!IsCrypted()) return CBasicKeyStore::GetKey(address, keyOut); @@ -128,7 +127,7 @@ bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const bool CCryptoKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector& vchPubKeyOut) const { - CRITICAL_BLOCK(cs_vMasterKey) + CRITICAL_BLOCK(cs_KeyStore) { if (!IsCrypted()) return CKeyStore::GetPubKey(address, vchPubKeyOut); @@ -146,7 +145,6 @@ bool CCryptoKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector 0); + bool result; + CRITICAL_BLOCK(cs_KeyStore) + result = (mapKeys.count(address) > 0); + return result; } bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const { - KeyMap::const_iterator mi = mapKeys.find(address); - if (mi != mapKeys.end()) + CRITICAL_BLOCK(cs_KeyStore) { - keyOut.SetSecret((*mi).second); - return true; + KeyMap::const_iterator mi = mapKeys.find(address); + if (mi != mapKeys.end()) + { + keyOut.SetSecret((*mi).second); + return true; + } } return false; } @@ -74,8 +81,6 @@ protected: bool Unlock(const CKeyingMaterial& vMasterKeyIn); public: - mutable CCriticalSection cs_vMasterKey; //No guarantees master key wont get locked before you can use it, so lock this first - CCryptoKeyStore() : fUseCrypto(false) { } @@ -89,18 +94,20 @@ public: { if (!IsCrypted()) return false; - return vMasterKey.empty(); + bool result; + CRITICAL_BLOCK(cs_KeyStore) + result = vMasterKey.empty(); + return result; } bool Lock() { - CRITICAL_BLOCK(cs_vMasterKey) - { - if (!SetCrypted()) - return false; + if (!SetCrypted()) + return false; + CRITICAL_BLOCK(cs_KeyStore) vMasterKey.clear(); - } + return true; } @@ -109,9 +116,12 @@ public: bool AddKey(const CKey& key); bool HaveKey(const CBitcoinAddress &address) const { - if (!IsCrypted()) - return CBasicKeyStore::HaveKey(address); - return mapCryptedKeys.count(address) > 0; + CRITICAL_BLOCK(cs_KeyStore) + { + if (!IsCrypted()) + return CBasicKeyStore::HaveKey(address); + return mapCryptedKeys.count(address) > 0; + } } bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const; bool GetPubKey(const CBitcoinAddress &address, std::vector& vchPubKeyOut) const; diff --git a/src/main.cpp b/src/main.cpp index f48331206..390632aaf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2879,7 +2879,7 @@ bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) reservekey.KeepKey(); // Track how many getdata requests this block gets - CRITICAL_BLOCK(wallet.cs_mapRequestCount) + CRITICAL_BLOCK(wallet.cs_wallet) wallet.mapRequestCount[pblock->GetHash()] = 0; // Process this block the same as if we had received it from another node diff --git a/src/rpc.cpp b/src/rpc.cpp index 62b2f82fb..5eb5669ac 100644 --- a/src/rpc.cpp +++ b/src/rpc.cpp @@ -346,55 +346,50 @@ Value getnewaddress(const Array& params, bool fHelp) CBitcoinAddress address(pwalletMain->GetOrReuseKeyFromPool()); // This could be done in the same main CS as GetKeyFromKeyPool. - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) - pwalletMain->SetAddressBookName(address, strAccount); + pwalletMain->SetAddressBookName(address, strAccount); return address.ToString(); } -// requires cs_main, cs_mapWallet, cs_mapAddressBook locks CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) { CWalletDB walletdb(pwalletMain->strWalletFile); CAccount account; - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) - { - walletdb.ReadAccount(strAccount, account); + walletdb.ReadAccount(strAccount, account); - bool bKeyUsed = false; + bool bKeyUsed = false; - // Check if the current key has been used - if (!account.vchPubKey.empty()) + // Check if the current key has been used + if (!account.vchPubKey.empty()) + { + CScript scriptPubKey; + scriptPubKey.SetBitcoinAddress(account.vchPubKey); + for (map::iterator it = pwalletMain->mapWallet.begin(); + it != pwalletMain->mapWallet.end() && !account.vchPubKey.empty(); + ++it) { - CScript scriptPubKey; - scriptPubKey.SetBitcoinAddress(account.vchPubKey); - for (map::iterator it = pwalletMain->mapWallet.begin(); - it != pwalletMain->mapWallet.end() && !account.vchPubKey.empty(); - ++it) - { - const CWalletTx& wtx = (*it).second; - BOOST_FOREACH(const CTxOut& txout, wtx.vout) - if (txout.scriptPubKey == scriptPubKey) - bKeyUsed = true; - } + const CWalletTx& wtx = (*it).second; + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + if (txout.scriptPubKey == scriptPubKey) + bKeyUsed = true; } + } - // Generate a new key - if (account.vchPubKey.empty() || bForceNew || bKeyUsed) + // Generate a new key + if (account.vchPubKey.empty() || bForceNew || bKeyUsed) + { + if (pwalletMain->GetKeyPoolSize() < 1) { - if (pwalletMain->GetKeyPoolSize() < 1) - { - if (bKeyUsed || bForceNew) - throw JSONRPCError(-12, "Error: Keypool ran out, please call topupkeypool first"); - } - else - { - account.vchPubKey = pwalletMain->GetOrReuseKeyFromPool(); - pwalletMain->SetAddressBookName(CBitcoinAddress(account.vchPubKey), strAccount); - walletdb.WriteAccount(strAccount, account); - } + if (bKeyUsed || bForceNew) + throw JSONRPCError(-12, "Error: Keypool ran out, please call topupkeypool first"); + } + else + { + account.vchPubKey = pwalletMain->GetOrReuseKeyFromPool(); + pwalletMain->SetAddressBookName(CBitcoinAddress(account.vchPubKey), strAccount); + walletdb.WriteAccount(strAccount, account); } } @@ -413,12 +408,7 @@ Value getaccountaddress(const Array& params, bool fHelp) Value ret; - CRITICAL_BLOCK(cs_main) - CRITICAL_BLOCK(pwalletMain->cs_mapWallet) - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) - { - ret = GetAccountAddress(strAccount).ToString(); - } + ret = GetAccountAddress(strAccount).ToString(); return ret; } @@ -442,20 +432,15 @@ Value setaccount(const Array& params, bool fHelp) strAccount = AccountFromValue(params[1]); // Detect when changing the account of an address that is the 'unused current key' of another account: - CRITICAL_BLOCK(cs_main) - CRITICAL_BLOCK(pwalletMain->cs_mapWallet) - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) + if (pwalletMain->mapAddressBook.count(address)) { - if (pwalletMain->mapAddressBook.count(address)) - { - string strOldAccount = pwalletMain->mapAddressBook[address]; - if (address == GetAccountAddress(strOldAccount)) - GetAccountAddress(strOldAccount, true); - } - - pwalletMain->SetAddressBookName(address, strAccount); + string strOldAccount = pwalletMain->mapAddressBook[address]; + if (address == GetAccountAddress(strOldAccount)) + GetAccountAddress(strOldAccount, true); } + pwalletMain->SetAddressBookName(address, strAccount); + return Value::null; } @@ -472,12 +457,9 @@ Value getaccount(const Array& params, bool fHelp) throw JSONRPCError(-5, "Invalid bitcoin address"); string strAccount; - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) - { - map::iterator mi = pwalletMain->mapAddressBook.find(address); - if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.empty()) - strAccount = (*mi).second; - } + map::iterator mi = pwalletMain->mapAddressBook.find(address); + if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.empty()) + strAccount = (*mi).second; return strAccount; } @@ -493,15 +475,12 @@ Value getaddressesbyaccount(const Array& params, bool fHelp) // Find all addresses that have the given account Array ret; - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook) { - BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook) - { - const CBitcoinAddress& address = item.first; - const string& strName = item.second; - if (strName == strAccount) - ret.push_back(address.ToString()); - } + const CBitcoinAddress& address = item.first; + const string& strName = item.second; + if (strName == strAccount) + ret.push_back(address.ToString()); } return ret; } @@ -548,16 +527,12 @@ Value sendtoaddress(const Array& params, bool fHelp) if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty()) wtx.mapValue["to"] = params[3].get_str(); - CRITICAL_BLOCK(cs_main) - CRITICAL_BLOCK(pwalletMain->cs_vMasterKey) - { - if(pwalletMain->IsLocked()) - throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first."); + if (pwalletMain->IsLocked()) + throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first."); - string strError = pwalletMain->SendMoneyToBitcoinAddress(address, nAmount, wtx); - if (strError != "") - throw JSONRPCError(-4, strError); - } + string strError = pwalletMain->SendMoneyToBitcoinAddress(address, nAmount, wtx); + if (strError != "") + throw JSONRPCError(-4, strError); return wtx.GetHash().GetHex(); } @@ -586,19 +561,16 @@ Value getreceivedbyaddress(const Array& params, bool fHelp) // Tally int64 nAmount = 0; - CRITICAL_BLOCK(pwalletMain->cs_mapWallet) + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { - for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) - { - const CWalletTx& wtx = (*it).second; - if (wtx.IsCoinBase() || !wtx.IsFinal()) - continue; + const CWalletTx& wtx = (*it).second; + if (wtx.IsCoinBase() || !wtx.IsFinal()) + continue; - BOOST_FOREACH(const CTxOut& txout, wtx.vout) - if (txout.scriptPubKey == scriptPubKey) - if (wtx.GetDepthInMainChain() >= nMinDepth) - nAmount += txout.nValue; - } + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + if (txout.scriptPubKey == scriptPubKey) + if (wtx.GetDepthInMainChain() >= nMinDepth) + nAmount += txout.nValue; } return ValueFromAmount(nAmount); @@ -607,15 +579,12 @@ Value getreceivedbyaddress(const Array& params, bool fHelp) void GetAccountAddresses(string strAccount, set& setAddress) { - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook) { - BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook) - { - const CBitcoinAddress& address = item.first; - const string& strName = item.second; - if (strName == strAccount) - setAddress.insert(address); - } + const CBitcoinAddress& address = item.first; + const string& strName = item.second; + if (strName == strAccount) + setAddress.insert(address); } } @@ -639,21 +608,18 @@ Value getreceivedbyaccount(const Array& params, bool fHelp) // Tally int64 nAmount = 0; - CRITICAL_BLOCK(pwalletMain->cs_mapWallet) + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { - for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) - { - const CWalletTx& wtx = (*it).second; - if (wtx.IsCoinBase() || !wtx.IsFinal()) - continue; + const CWalletTx& wtx = (*it).second; + if (wtx.IsCoinBase() || !wtx.IsFinal()) + continue; - BOOST_FOREACH(const CTxOut& txout, wtx.vout) - { - CBitcoinAddress address; - if (ExtractAddress(txout.scriptPubKey, pwalletMain, address) && setAddress.count(address)) - if (wtx.GetDepthInMainChain() >= nMinDepth) - nAmount += txout.nValue; - } + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + { + CBitcoinAddress address; + if (ExtractAddress(txout.scriptPubKey, pwalletMain, address) && setAddress.count(address)) + if (wtx.GetDepthInMainChain() >= nMinDepth) + nAmount += txout.nValue; } } @@ -664,27 +630,25 @@ Value getreceivedbyaccount(const Array& params, bool fHelp) int64 GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth) { int64 nBalance = 0; - CRITICAL_BLOCK(pwalletMain->cs_mapWallet) - { - // Tally wallet transactions - for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) - { - const CWalletTx& wtx = (*it).second; - if (!wtx.IsFinal()) - continue; - int64 nGenerated, nReceived, nSent, nFee; - wtx.GetAccountAmounts(strAccount, nGenerated, nReceived, nSent, nFee); + // Tally wallet transactions + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + if (!wtx.IsFinal()) + continue; - if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth) - nBalance += nReceived; - nBalance += nGenerated - nSent - nFee; - } + int64 nGenerated, nReceived, nSent, nFee; + wtx.GetAccountAmounts(strAccount, nGenerated, nReceived, nSent, nFee); - // Tally internal accounting entries - nBalance += walletdb.GetAccountCreditDebit(strAccount); + if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth) + nBalance += nReceived; + nBalance += nGenerated - nSent - nFee; } + // Tally internal accounting entries + nBalance += walletdb.GetAccountCreditDebit(strAccount); + return nBalance; } @@ -763,33 +727,31 @@ Value movecmd(const Array& params, bool fHelp) if (params.size() > 4) strComment = params[4].get_str(); - CRITICAL_BLOCK(pwalletMain->cs_mapWallet) - { - CWalletDB walletdb(pwalletMain->strWalletFile); - walletdb.TxnBegin(); - - int64 nNow = GetAdjustedTime(); - - // Debit - CAccountingEntry debit; - debit.strAccount = strFrom; - debit.nCreditDebit = -nAmount; - debit.nTime = nNow; - debit.strOtherAccount = strTo; - debit.strComment = strComment; - walletdb.WriteAccountingEntry(debit); - - // Credit - CAccountingEntry credit; - credit.strAccount = strTo; - credit.nCreditDebit = nAmount; - credit.nTime = nNow; - credit.strOtherAccount = strFrom; - credit.strComment = strComment; - walletdb.WriteAccountingEntry(credit); - - walletdb.TxnCommit(); - } + CWalletDB walletdb(pwalletMain->strWalletFile); + walletdb.TxnBegin(); + + int64 nNow = GetAdjustedTime(); + + // Debit + CAccountingEntry debit; + debit.strAccount = strFrom; + debit.nCreditDebit = -nAmount; + debit.nTime = nNow; + debit.strOtherAccount = strTo; + debit.strComment = strComment; + walletdb.WriteAccountingEntry(debit); + + // Credit + CAccountingEntry credit; + credit.strAccount = strTo; + credit.nCreditDebit = nAmount; + credit.nTime = nNow; + credit.strOtherAccount = strFrom; + credit.strComment = strComment; + walletdb.WriteAccountingEntry(credit); + + walletdb.TxnCommit(); + return true; } @@ -822,23 +784,18 @@ Value sendfrom(const Array& params, bool fHelp) if (params.size() > 5 && params[5].type() != null_type && !params[5].get_str().empty()) wtx.mapValue["to"] = params[5].get_str(); - CRITICAL_BLOCK(cs_main) - CRITICAL_BLOCK(pwalletMain->cs_mapWallet) - CRITICAL_BLOCK(pwalletMain->cs_vMasterKey) - { - if(pwalletMain->IsLocked()) - throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first."); - - // Check funds - int64 nBalance = GetAccountBalance(strAccount, nMinDepth); - if (nAmount > nBalance) - throw JSONRPCError(-6, "Account has insufficient funds"); - - // Send - string strError = pwalletMain->SendMoneyToBitcoinAddress(address, nAmount, wtx); - if (strError != "") - throw JSONRPCError(-4, strError); - } + if (pwalletMain->IsLocked()) + throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first."); + + // Check funds + int64 nBalance = GetAccountBalance(strAccount, nMinDepth); + if (nAmount > nBalance) + throw JSONRPCError(-6, "Account has insufficient funds"); + + // Send + string strError = pwalletMain->SendMoneyToBitcoinAddress(address, nAmount, wtx); + if (strError != "") + throw JSONRPCError(-4, strError); return wtx.GetHash().GetHex(); } @@ -889,31 +846,26 @@ Value sendmany(const Array& params, bool fHelp) vecSend.push_back(make_pair(scriptPubKey, nAmount)); } - CRITICAL_BLOCK(cs_main) - CRITICAL_BLOCK(pwalletMain->cs_mapWallet) - CRITICAL_BLOCK(pwalletMain->cs_vMasterKey) + if (pwalletMain->IsLocked()) + throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first."); + + // Check funds + int64 nBalance = GetAccountBalance(strAccount, nMinDepth); + if (totalAmount > nBalance) + throw JSONRPCError(-6, "Account has insufficient funds"); + + // Send + CReserveKey keyChange(pwalletMain); + int64 nFeeRequired = 0; + bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired); + if (!fCreated) { - if(pwalletMain->IsLocked()) - throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first."); - - // Check funds - int64 nBalance = GetAccountBalance(strAccount, nMinDepth); - if (totalAmount > nBalance) - throw JSONRPCError(-6, "Account has insufficient funds"); - - // Send - CReserveKey keyChange(pwalletMain); - int64 nFeeRequired = 0; - bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired); - if (!fCreated) - { - if (totalAmount + nFeeRequired > pwalletMain->GetBalance()) - throw JSONRPCError(-6, "Insufficient funds"); - throw JSONRPCError(-4, "Transaction creation failed"); - } - if (!pwalletMain->CommitTransaction(wtx, keyChange)) - throw JSONRPCError(-4, "Transaction commit failed"); + if (totalAmount + nFeeRequired > pwalletMain->GetBalance()) + throw JSONRPCError(-6, "Insufficient funds"); + throw JSONRPCError(-4, "Transaction creation failed"); } + if (!pwalletMain->CommitTransaction(wtx, keyChange)) + throw JSONRPCError(-4, "Transaction commit failed"); return wtx.GetHash().GetHex(); } @@ -944,68 +896,62 @@ Value ListReceived(const Array& params, bool fByAccounts) // Tally map mapTally; - CRITICAL_BLOCK(pwalletMain->cs_mapWallet) + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { - for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) - { - const CWalletTx& wtx = (*it).second; - if (wtx.IsCoinBase() || !wtx.IsFinal()) - continue; + const CWalletTx& wtx = (*it).second; + if (wtx.IsCoinBase() || !wtx.IsFinal()) + continue; - int nDepth = wtx.GetDepthInMainChain(); - if (nDepth < nMinDepth) - continue; + int nDepth = wtx.GetDepthInMainChain(); + if (nDepth < nMinDepth) + continue; - BOOST_FOREACH(const CTxOut& txout, wtx.vout) - { - CBitcoinAddress address; - if (!ExtractAddress(txout.scriptPubKey, pwalletMain, address) || !address.IsValid()) - continue; + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + { + CBitcoinAddress address; + if (!ExtractAddress(txout.scriptPubKey, pwalletMain, address) || !address.IsValid()) + continue; - tallyitem& item = mapTally[address]; - item.nAmount += txout.nValue; - item.nConf = min(item.nConf, nDepth); - } + tallyitem& item = mapTally[address]; + item.nAmount += txout.nValue; + item.nConf = min(item.nConf, nDepth); } } // Reply Array ret; map mapAccountTally; - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook) { - BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook) - { - const CBitcoinAddress& address = item.first; - const string& strAccount = item.second; - map::iterator it = mapTally.find(address); - if (it == mapTally.end() && !fIncludeEmpty) - continue; + const CBitcoinAddress& address = item.first; + const string& strAccount = item.second; + map::iterator it = mapTally.find(address); + if (it == mapTally.end() && !fIncludeEmpty) + continue; - int64 nAmount = 0; - int nConf = INT_MAX; - if (it != mapTally.end()) - { - nAmount = (*it).second.nAmount; - nConf = (*it).second.nConf; - } + int64 nAmount = 0; + int nConf = INT_MAX; + if (it != mapTally.end()) + { + nAmount = (*it).second.nAmount; + nConf = (*it).second.nConf; + } - if (fByAccounts) - { - tallyitem& item = mapAccountTally[strAccount]; - item.nAmount += nAmount; - item.nConf = min(item.nConf, nConf); - } - else - { - Object obj; - obj.push_back(Pair("address", address.ToString())); - obj.push_back(Pair("account", strAccount)); - obj.push_back(Pair("label", strAccount)); // deprecated - obj.push_back(Pair("amount", ValueFromAmount(nAmount))); - obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 : nConf))); - ret.push_back(obj); - } + if (fByAccounts) + { + tallyitem& item = mapAccountTally[strAccount]; + item.nAmount += nAmount; + item.nConf = min(item.nConf, nConf); + } + else + { + Object obj; + obj.push_back(Pair("address", address.ToString())); + obj.push_back(Pair("account", strAccount)); + obj.push_back(Pair("label", strAccount)); // deprecated + obj.push_back(Pair("amount", ValueFromAmount(nAmount))); + obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 : nConf))); + ret.push_back(obj); } } @@ -1107,27 +1053,23 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe // Received if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth) - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived) { - BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived) + string account; + if (pwalletMain->mapAddressBook.count(r.first)) + account = pwalletMain->mapAddressBook[r.first]; + if (fAllAccounts || (account == strAccount)) { - string account; - if (pwalletMain->mapAddressBook.count(r.first)) - account = pwalletMain->mapAddressBook[r.first]; - if (fAllAccounts || (account == strAccount)) - { - Object entry; - entry.push_back(Pair("account", account)); - entry.push_back(Pair("address", r.first.ToString())); - entry.push_back(Pair("category", "receive")); - entry.push_back(Pair("amount", ValueFromAmount(r.second))); - if (fLong) - WalletTxToJSON(wtx, entry); - ret.push_back(entry); - } + Object entry; + entry.push_back(Pair("account", account)); + entry.push_back(Pair("address", r.first.ToString())); + entry.push_back(Pair("category", "receive")); + entry.push_back(Pair("amount", ValueFromAmount(r.second))); + if (fLong) + WalletTxToJSON(wtx, entry); + ret.push_back(entry); } } - } void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Array& ret) @@ -1167,41 +1109,38 @@ Value listtransactions(const Array& params, bool fHelp) Array ret; CWalletDB walletdb(pwalletMain->strWalletFile); - CRITICAL_BLOCK(pwalletMain->cs_mapWallet) - { - // Firs: get all CWalletTx and CAccountingEntry into a sorted-by-time multimap: - typedef pair TxPair; - typedef multimap TxItems; - TxItems txByTime; + // Firs: get all CWalletTx and CAccountingEntry into a sorted-by-time multimap: + typedef pair TxPair; + typedef multimap TxItems; + TxItems txByTime; - for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) - { - CWalletTx* wtx = &((*it).second); - txByTime.insert(make_pair(wtx->GetTxTime(), TxPair(wtx, (CAccountingEntry*)0))); - } - list acentries; - walletdb.ListAccountCreditDebit(strAccount, acentries); - BOOST_FOREACH(CAccountingEntry& entry, acentries) - { - txByTime.insert(make_pair(entry.nTime, TxPair((CWalletTx*)0, &entry))); - } + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + { + CWalletTx* wtx = &((*it).second); + txByTime.insert(make_pair(wtx->GetTxTime(), TxPair(wtx, (CAccountingEntry*)0))); + } + list acentries; + walletdb.ListAccountCreditDebit(strAccount, acentries); + BOOST_FOREACH(CAccountingEntry& entry, acentries) + { + 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) - { - CWalletTx *const pwtx = (*it).second.first; - if (pwtx != 0) - ListTransactions(*pwtx, strAccount, 0, true, ret); - CAccountingEntry *const pacentry = (*it).second.second; - if (pacentry != 0) - AcentryToJSON(*pacentry, strAccount, ret); - - if (ret.size() >= nCount) break; - } - // ret is now newest to oldest + // 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) + { + CWalletTx *const pwtx = (*it).second.first; + if (pwtx != 0) + ListTransactions(*pwtx, strAccount, 0, true, ret); + CAccountingEntry *const pacentry = (*it).second.second; + if (pacentry != 0) + AcentryToJSON(*pacentry, strAccount, ret); + + if (ret.size() >= nCount) break; } + // ret is now newest to oldest // Make sure we return only last nCount items (sends-to-self might give us an extra): if (ret.size() > nCount) @@ -1227,34 +1166,30 @@ Value listaccounts(const Array& params, bool fHelp) nMinDepth = params[0].get_int(); map mapAccountBalances; - CRITICAL_BLOCK(pwalletMain->cs_mapWallet) - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) - { - BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& entry, pwalletMain->mapAddressBook) { - if (pwalletMain->HaveKey(entry.first)) // This address belongs to me - mapAccountBalances[entry.second] = 0; - } + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& entry, pwalletMain->mapAddressBook) { + if (pwalletMain->HaveKey(entry.first)) // This address belongs to me + mapAccountBalances[entry.second] = 0; + } - for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + int64 nGeneratedImmature, nGeneratedMature, nFee; + string strSentAccount; + list > listReceived; + list > listSent; + wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount); + mapAccountBalances[strSentAccount] -= nFee; + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& s, listSent) + mapAccountBalances[strSentAccount] -= s.second; + if (wtx.GetDepthInMainChain() >= nMinDepth) { - const CWalletTx& wtx = (*it).second; - int64 nGeneratedImmature, nGeneratedMature, nFee; - string strSentAccount; - list > listReceived; - list > listSent; - wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount); - mapAccountBalances[strSentAccount] -= nFee; - BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& s, listSent) - mapAccountBalances[strSentAccount] -= s.second; - if (wtx.GetDepthInMainChain() >= nMinDepth) - { - mapAccountBalances[""] += nGeneratedMature; - BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived) - if (pwalletMain->mapAddressBook.count(r.first)) - mapAccountBalances[pwalletMain->mapAddressBook[r.first]] += r.second; - else - mapAccountBalances[""] += r.second; - } + mapAccountBalances[""] += nGeneratedMature; + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived) + if (pwalletMain->mapAddressBook.count(r.first)) + mapAccountBalances[pwalletMain->mapAddressBook[r.first]] += r.second; + else + mapAccountBalances[""] += r.second; } } @@ -1281,27 +1216,25 @@ Value gettransaction(const Array& params, bool fHelp) hash.SetHex(params[0].get_str()); Object entry; - CRITICAL_BLOCK(pwalletMain->cs_mapWallet) - { - if (!pwalletMain->mapWallet.count(hash)) - throw JSONRPCError(-5, "Invalid or non-wallet transaction id"); - const CWalletTx& wtx = pwalletMain->mapWallet[hash]; - int64 nCredit = wtx.GetCredit(); - int64 nDebit = wtx.GetDebit(); - int64 nNet = nCredit - nDebit; - int64 nFee = (wtx.IsFromMe() ? wtx.GetValueOut() - nDebit : 0); + if (!pwalletMain->mapWallet.count(hash)) + throw JSONRPCError(-5, "Invalid or non-wallet transaction id"); + const CWalletTx& wtx = pwalletMain->mapWallet[hash]; - entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee))); - if (wtx.IsFromMe()) - entry.push_back(Pair("fee", ValueFromAmount(nFee))); + int64 nCredit = wtx.GetCredit(); + int64 nDebit = wtx.GetDebit(); + int64 nNet = nCredit - nDebit; + int64 nFee = (wtx.IsFromMe() ? wtx.GetValueOut() - nDebit : 0); - WalletTxToJSON(pwalletMain->mapWallet[hash], entry); + entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee))); + if (wtx.IsFromMe()) + entry.push_back(Pair("fee", ValueFromAmount(nFee))); - Array details; - ListTransactions(pwalletMain->mapWallet[hash], "*", 0, false, details); - entry.push_back(Pair("details", details)); - } + WalletTxToJSON(pwalletMain->mapWallet[hash], entry); + + Array details; + ListTransactions(pwalletMain->mapWallet[hash], "*", 0, false, details); + entry.push_back(Pair("details", details)); return entry; } @@ -1332,13 +1265,10 @@ Value keypoolrefill(const Array& params, bool fHelp) "keypoolrefill\n" "Fills the keypool."); - CRITICAL_BLOCK(pwalletMain->cs_vMasterKey) - { - if (pwalletMain->IsLocked()) - throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first."); + if (pwalletMain->IsLocked()) + throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first."); - pwalletMain->TopUpKeyPool(); - } + pwalletMain->TopUpKeyPool(); if (pwalletMain->GetKeyPoolSize() < GetArg("-keypool", 100)) throw JSONRPCError(-4, "Error refreshing keypool."); @@ -1407,24 +1337,21 @@ Value walletpassphrase(const Array& params, bool fHelp) mlock(&strWalletPass[0], strWalletPass.capacity()); strWalletPass = params[0].get_str(); - CRITICAL_BLOCK(pwalletMain->cs_vMasterKey) + if (strWalletPass.length() > 0) { - if (strWalletPass.length() > 0) + if (!pwalletMain->Unlock(strWalletPass)) { - if (!pwalletMain->Unlock(strWalletPass)) - { - fill(strWalletPass.begin(), strWalletPass.end(), '\0'); - munlock(&strWalletPass[0], strWalletPass.capacity()); - throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect."); - } fill(strWalletPass.begin(), strWalletPass.end(), '\0'); munlock(&strWalletPass[0], strWalletPass.capacity()); + throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect."); } - else - throw runtime_error( - "walletpassphrase \n" - "Stores the wallet decryption key in memory for seconds."); + fill(strWalletPass.begin(), strWalletPass.end(), '\0'); + munlock(&strWalletPass[0], strWalletPass.capacity()); } + else + throw runtime_error( + "walletpassphrase \n" + "Stores the wallet decryption key in memory for seconds."); CreateThread(ThreadTopUpKeyPool, NULL); int* pnSleepTime = new int(params[1].get_int()); @@ -1553,11 +1480,8 @@ Value validateaddress(const Array& params, bool fHelp) string currentAddress = address.ToString(); ret.push_back(Pair("address", currentAddress)); ret.push_back(Pair("ismine", (pwalletMain->HaveKey(address) > 0))); - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) - { - if (pwalletMain->mapAddressBook.count(address)) - ret.push_back(Pair("account", pwalletMain->mapAddressBook[address])); - } + if (pwalletMain->mapAddressBook.count(address)) + ret.push_back(Pair("account", pwalletMain->mapAddressBook[address])); } return ret; } @@ -2233,7 +2157,10 @@ void ThreadRPCServer2(void* parg) try { // Execute - Value result = (*(*mi).second)(params, false); + Value result; + CRITICAL_BLOCK(cs_main) + CRITICAL_BLOCK(pwalletMain->cs_wallet) + result = (*(*mi).second)(params, false); // Send reply string strReply = JSONRPCReply(result, Value::null, id); diff --git a/src/script.cpp b/src/script.cpp index d0c6a1149..6e7bcb5e1 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -1033,48 +1033,45 @@ bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash return false; // Compile solution - CRITICAL_BLOCK(keystore.cs_KeyStore) + BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution) { - BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution) + if (item.first == OP_PUBKEY) { - if (item.first == OP_PUBKEY) + // Sign + const valtype& vchPubKey = item.second; + CKey key; + if (!keystore.GetKey(Hash160(vchPubKey), key)) + return false; + if (key.GetPubKey() != vchPubKey) + return false; + if (hash != 0) { - // Sign - const valtype& vchPubKey = item.second; - CKey key; - if (!keystore.GetKey(Hash160(vchPubKey), key)) - return false; - if (key.GetPubKey() != vchPubKey) + vector vchSig; + if (!key.Sign(hash, vchSig)) return false; - if (hash != 0) - { - vector vchSig; - if (!key.Sign(hash, vchSig)) - return false; - vchSig.push_back((unsigned char)nHashType); - scriptSigRet << vchSig; - } + vchSig.push_back((unsigned char)nHashType); + scriptSigRet << vchSig; } - else if (item.first == OP_PUBKEYHASH) + } + else if (item.first == OP_PUBKEYHASH) + { + // Sign and give pubkey + CKey key; + if (!keystore.GetKey(uint160(item.second), key)) + return false; + if (hash != 0) { - // Sign and give pubkey - CKey key; - if (!keystore.GetKey(uint160(item.second), key)) + vector vchSig; + if (!key.Sign(hash, vchSig)) return false; - if (hash != 0) - { - vector vchSig; - if (!key.Sign(hash, vchSig)) - return false; - vchSig.push_back((unsigned char)nHashType); - scriptSigRet << vchSig << key.GetPubKey(); - } - } - else - { - return false; + vchSig.push_back((unsigned char)nHashType); + scriptSigRet << vchSig << key.GetPubKey(); } } + else + { + return false; + } } return true; @@ -1095,35 +1092,31 @@ bool IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) return false; // Compile solution - CRITICAL_BLOCK(keystore.cs_KeyStore) + BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution) { - BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution) + if (item.first == OP_PUBKEY) { - if (item.first == OP_PUBKEY) - { - const valtype& vchPubKey = item.second; - vector vchPubKeyFound; - if (!keystore.GetPubKey(Hash160(vchPubKey), vchPubKeyFound)) - return false; - if (vchPubKeyFound != vchPubKey) - return false; - } - else if (item.first == OP_PUBKEYHASH) - { - if (!keystore.HaveKey(uint160(item.second))) - return false; - } - else - { + const valtype& vchPubKey = item.second; + vector vchPubKeyFound; + if (!keystore.GetPubKey(Hash160(vchPubKey), vchPubKeyFound)) return false; - } + if (vchPubKeyFound != vchPubKey) + return false; + } + else if (item.first == OP_PUBKEYHASH) + { + if (!keystore.HaveKey(uint160(item.second))) + return false; + } + else + { + return false; } } return true; } -// requires either keystore==0, or a lock on keystore->cs_KeyStore bool static ExtractAddressInner(const CScript& scriptPubKey, const CKeyStore* keystore, CBitcoinAddress& addressRet) { vector > vSolution; @@ -1146,8 +1139,7 @@ bool static ExtractAddressInner(const CScript& scriptPubKey, const CKeyStore* ke bool ExtractAddress(const CScript& scriptPubKey, const CKeyStore* keystore, CBitcoinAddress& addressRet) { if (keystore) - CRITICAL_BLOCK(keystore->cs_KeyStore) - return ExtractAddressInner(scriptPubKey, keystore, addressRet); + return ExtractAddressInner(scriptPubKey, keystore, addressRet); else return ExtractAddressInner(scriptPubKey, NULL, addressRet); return false; diff --git a/src/ui.cpp b/src/ui.cpp index 372808f1a..867c9c0a0 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -862,7 +862,7 @@ void CMainFrame::OnIdle(wxIdleEvent& event) // Collect list of wallet transactions and sort newest first bool fEntered = false; vector > vSorted; - TRY_CRITICAL_BLOCK(pwalletMain->cs_mapWallet) + TRY_CRITICAL_BLOCK(pwalletMain->cs_wallet) { printf("RefreshListCtrl starting\n"); fEntered = true; @@ -890,7 +890,7 @@ void CMainFrame::OnIdle(wxIdleEvent& event) if (fShutdown) return; bool fEntered = false; - TRY_CRITICAL_BLOCK(pwalletMain->cs_mapWallet) + TRY_CRITICAL_BLOCK(pwalletMain->cs_wallet) { fEntered = true; uint256& hash = vSorted[i++].second; @@ -913,7 +913,7 @@ void CMainFrame::OnIdle(wxIdleEvent& event) static int64 nLastTime; if (GetTime() > nLastTime + 30) { - TRY_CRITICAL_BLOCK(pwalletMain->cs_mapWallet) + TRY_CRITICAL_BLOCK(pwalletMain->cs_wallet) { nLastTime = GetTime(); for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) @@ -937,7 +937,7 @@ void CMainFrame::RefreshStatusColumn() if (nTop == nLastTop && pindexLastBest == pindexBest) return; - TRY_CRITICAL_BLOCK(pwalletMain->cs_mapWallet) + TRY_CRITICAL_BLOCK(pwalletMain->cs_wallet) { int nStart = nTop; int nEnd = min(nStart + 100, m_listCtrl->GetItemCount()); @@ -1057,7 +1057,7 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) // Update listctrl contents if (!pwalletMain->vWalletUpdated.empty()) { - TRY_CRITICAL_BLOCK(pwalletMain->cs_mapWallet) + TRY_CRITICAL_BLOCK(pwalletMain->cs_wallet) { string strTop; if (m_listCtrl->GetItemCount()) @@ -1075,7 +1075,7 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) } // Balance total - TRY_CRITICAL_BLOCK(pwalletMain->cs_mapWallet) + TRY_CRITICAL_BLOCK(pwalletMain->cs_wallet) { fPaintedBalance = true; m_staticTextBalance->SetLabel(FormatMoney(pwalletMain->GetBalance()) + " "); @@ -1420,7 +1420,7 @@ void CMainFrame::OnListItemActivated(wxListEvent& event) { uint256 hash((string)GetItemText(m_listCtrl, event.GetIndex(), 1)); CWalletTx wtx; - CRITICAL_BLOCK(pwalletMain->cs_mapWallet) + CRITICAL_BLOCK(pwalletMain->cs_wallet) { map::iterator mi = pwalletMain->mapWallet.find(hash); if (mi == pwalletMain->mapWallet.end()) @@ -1662,7 +1662,7 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails strHTML += HtmlEscape(wtx.ToString(), true); strHTML += "
Inputs:
"; - CRITICAL_BLOCK(pwalletMain->cs_mapWallet) + CRITICAL_BLOCK(pwalletMain->cs_wallet) { BOOST_FOREACH(const CTxIn& txin, wtx.vin) { @@ -2621,7 +2621,6 @@ CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInit m_listCtrlReceiving->SetFocus(); // Fill listctrl with address book data - CRITICAL_BLOCK(pwalletMain->cs_KeyStore) CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) { string strDefaultReceiving = (string)pframeMain->m_textCtrlAddress->GetValue(); diff --git a/src/wallet.cpp b/src/wallet.cpp index 6519ac637..745fbefdb 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -33,7 +33,7 @@ bool CWallet::AddCryptedKey(const vector &vchPubKey, const vector return false; if (!fFileBacked) return true; - CRITICAL_BLOCK(cs_pwalletdbEncryption) + CRITICAL_BLOCK(cs_wallet) { if (pwalletdbEncryption) return pwalletdbEncryption->WriteCryptedKey(vchPubKey, vchCryptedSecret); @@ -44,14 +44,13 @@ bool CWallet::AddCryptedKey(const vector &vchPubKey, const vector bool CWallet::Unlock(const string& strWalletPassphrase) { - CRITICAL_BLOCK(cs_vMasterKey) - { - if (!IsLocked()) - return false; + if (!IsLocked()) + return false; - CCrypter crypter; - CKeyingMaterial vMasterKey; + CCrypter crypter; + CKeyingMaterial vMasterKey; + CRITICAL_BLOCK(cs_wallet) BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys) { if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod)) @@ -61,16 +60,15 @@ bool CWallet::Unlock(const string& strWalletPassphrase) if (CCryptoKeyStore::Unlock(vMasterKey)) return true; } - } return false; } bool CWallet::ChangeWalletPassphrase(const string& strOldWalletPassphrase, const string& strNewWalletPassphrase) { - CRITICAL_BLOCK(cs_vMasterKey) - { - bool fWasLocked = IsLocked(); + bool fWasLocked = IsLocked(); + CRITICAL_BLOCK(cs_wallet) + { Lock(); CCrypter crypter; @@ -79,7 +77,7 @@ bool CWallet::ChangeWalletPassphrase(const string& strOldWalletPassphrase, const { if(!crypter.SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod)) return false; - if(!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey)) + if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey)) return false; if (CCryptoKeyStore::Unlock(vMasterKey)) { @@ -107,6 +105,7 @@ bool CWallet::ChangeWalletPassphrase(const string& strOldWalletPassphrase, const } } } + return false; } @@ -125,44 +124,42 @@ public: bool CWallet::EncryptWallet(const string& strWalletPassphrase) { - CRITICAL_BLOCK(cs_KeyStore) - CRITICAL_BLOCK(cs_vMasterKey) - CRITICAL_BLOCK(cs_pwalletdbEncryption) - { - if (IsCrypted()) - return false; + if (IsCrypted()) + return false; - CKeyingMaterial vMasterKey; - RandAddSeedPerfmon(); + CKeyingMaterial vMasterKey; + RandAddSeedPerfmon(); - vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE); - RAND_bytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE); + vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE); + RAND_bytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE); - CMasterKey kMasterKey; + CMasterKey kMasterKey; - RandAddSeedPerfmon(); - kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE); - RAND_bytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE); + RandAddSeedPerfmon(); + kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE); + RAND_bytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE); - CCrypter crypter; - int64 nStartTime = GetTimeMillis(); - crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod); - kMasterKey.nDeriveIterations = 2500000 / ((double)(GetTimeMillis() - nStartTime)); + CCrypter crypter; + int64 nStartTime = GetTimeMillis(); + crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod); + kMasterKey.nDeriveIterations = 2500000 / ((double)(GetTimeMillis() - nStartTime)); - nStartTime = GetTimeMillis(); - crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod); - kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2; + nStartTime = GetTimeMillis(); + crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod); + kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2; - if (kMasterKey.nDeriveIterations < 25000) - kMasterKey.nDeriveIterations = 25000; + if (kMasterKey.nDeriveIterations < 25000) + kMasterKey.nDeriveIterations = 25000; - printf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations); + printf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations); - if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod)) - return false; - if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey)) - return false; + if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod)) + return false; + if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey)) + return false; + CRITICAL_BLOCK(cs_wallet) + { mapMasterKeys[++nMasterKeyMaxID] = kMasterKey; if (fFileBacked) { @@ -191,6 +188,7 @@ bool CWallet::EncryptWallet(const string& strWalletPassphrase) Lock(); } + return true; } @@ -199,7 +197,7 @@ void CWallet::WalletUpdateSpent(const CTransaction &tx) // Anytime a signature is successfully verified, it's proof the outpoint is spent. // Update the wallet spent flag if it doesn't know due to wallet.dat being // restored from backup or the user making copies of wallet.dat. - CRITICAL_BLOCK(cs_mapWallet) + CRITICAL_BLOCK(cs_wallet) { BOOST_FOREACH(const CTxIn& txin, tx.vin) { @@ -222,7 +220,7 @@ void CWallet::WalletUpdateSpent(const CTransaction &tx) bool CWallet::AddToWallet(const CWalletTx& wtxIn) { uint256 hash = wtxIn.GetHash(); - CRITICAL_BLOCK(cs_mapWallet) + CRITICAL_BLOCK(cs_wallet) { // Inserts only if not already there, returns tx inserted or tx found pair::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn)); @@ -290,18 +288,21 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn) bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate) { uint256 hash = tx.GetHash(); - bool fExisted = mapWallet.count(hash); - if (fExisted && !fUpdate) return false; - if (fExisted || IsMine(tx) || IsFromMe(tx)) + CRITICAL_BLOCK(cs_wallet) { - CWalletTx wtx(this,tx); - // Get merkle branch if transaction was found in a block - if (pblock) - wtx.SetMerkleBranch(pblock); - return AddToWallet(wtx); + bool fExisted = mapWallet.count(hash); + if (fExisted && !fUpdate) return false; + if (fExisted || IsMine(tx) || IsFromMe(tx)) + { + CWalletTx wtx(this,tx); + // Get merkle branch if transaction was found in a block + if (pblock) + wtx.SetMerkleBranch(pblock); + return AddToWallet(wtx); + } + else + WalletUpdateSpent(tx); } - else - WalletUpdateSpent(tx); return false; } @@ -309,7 +310,7 @@ bool CWallet::EraseFromWallet(uint256 hash) { if (!fFileBacked) return false; - CRITICAL_BLOCK(cs_mapWallet) + CRITICAL_BLOCK(cs_wallet) { if (mapWallet.erase(hash)) CWalletDB(strWalletFile).EraseTx(hash); @@ -320,7 +321,7 @@ bool CWallet::EraseFromWallet(uint256 hash) bool CWallet::IsMine(const CTxIn &txin) const { - CRITICAL_BLOCK(cs_mapWallet) + CRITICAL_BLOCK(cs_wallet) { map::const_iterator mi = mapWallet.find(txin.prevout.hash); if (mi != mapWallet.end()) @@ -336,7 +337,7 @@ bool CWallet::IsMine(const CTxIn &txin) const int64 CWallet::GetDebit(const CTxIn &txin) const { - CRITICAL_BLOCK(cs_mapWallet) + CRITICAL_BLOCK(cs_wallet) { map::const_iterator mi = mapWallet.find(txin.prevout.hash); if (mi != mapWallet.end()) @@ -352,17 +353,20 @@ int64 CWallet::GetDebit(const CTxIn &txin) const int64 CWalletTx::GetTxTime() const { - if (!fTimeReceivedIsTxTime && hashBlock != 0) + CRITICAL_BLOCK(cs_main) { - // If we did not receive the transaction directly, we rely on the block's - // time to figure out when it happened. We use the median over a range - // of blocks to try to filter out inaccurate block times. - map::iterator mi = mapBlockIndex.find(hashBlock); - if (mi != mapBlockIndex.end()) + if (!fTimeReceivedIsTxTime && hashBlock != 0) { - CBlockIndex* pindex = (*mi).second; - if (pindex) - return pindex->GetMedianTime(); + // If we did not receive the transaction directly, we rely on the block's + // time to figure out when it happened. We use the median over a range + // of blocks to try to filter out inaccurate block times. + map::iterator mi = mapBlockIndex.find(hashBlock); + if (mi != mapBlockIndex.end()) + { + CBlockIndex* pindex = (*mi).second; + if (pindex) + return pindex->GetMedianTime(); + } } } return nTimeReceived; @@ -372,7 +376,7 @@ int CWalletTx::GetRequestCount() const { // Returns -1 if it wasn't being tracked int nRequests = -1; - CRITICAL_BLOCK(pwallet->cs_mapRequestCount) + CRITICAL_BLOCK(pwallet->cs_wallet) { if (IsCoinBase()) { @@ -478,7 +482,7 @@ void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, i nSent += s.second; nFee = allFee; } - CRITICAL_BLOCK(pwallet->cs_mapAddressBook) + CRITICAL_BLOCK(pwallet->cs_wallet) { BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listReceived) { @@ -508,7 +512,7 @@ void CWalletTx::AddSupportingTransactions(CTxDB& txdb) vWorkQueue.push_back(txin.prevout.hash); // This critsect is OK because txdb is already open - CRITICAL_BLOCK(pwallet->cs_mapWallet) + CRITICAL_BLOCK(pwallet->cs_wallet) { map mapWalletPrev; set setAlreadyDone; @@ -564,7 +568,7 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) int ret = 0; CBlockIndex* pindex = pindexStart; - CRITICAL_BLOCK(cs_mapWallet) + CRITICAL_BLOCK(cs_wallet) { while (pindex) { @@ -585,7 +589,7 @@ void CWallet::ReacceptWalletTransactions() { CTxDB txdb("r"); bool fRepeat = true; - while (fRepeat) CRITICAL_BLOCK(cs_mapWallet) + while (fRepeat) CRITICAL_BLOCK(cs_wallet) { fRepeat = false; vector vMissingTx; @@ -688,7 +692,7 @@ void CWallet::ResendWalletTransactions() // Rebroadcast any of our txes that aren't in a block yet printf("ResendWalletTransactions()\n"); CTxDB txdb("r"); - CRITICAL_BLOCK(cs_mapWallet) + CRITICAL_BLOCK(cs_wallet) { // Sort them in chronological order multimap mapSorted; @@ -722,7 +726,7 @@ void CWallet::ResendWalletTransactions() int64 CWallet::GetBalance() const { int64 nTotal = 0; - CRITICAL_BLOCK(cs_mapWallet) + CRITICAL_BLOCK(cs_wallet) { for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) { @@ -749,7 +753,7 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfThe vector > > vValue; int64 nTotalLower = 0; - CRITICAL_BLOCK(cs_mapWallet) + CRITICAL_BLOCK(cs_wallet) { vector vCoins; vCoins.reserve(mapWallet.size()); @@ -907,10 +911,10 @@ bool CWallet::CreateTransaction(const vector >& vecSend, CW wtxNew.pwallet = this; CRITICAL_BLOCK(cs_main) + CRITICAL_BLOCK(cs_wallet) { // txdb must be opened before the mapWallet lock CTxDB txdb("r"); - CRITICAL_BLOCK(cs_mapWallet) { nFeeRet = nTransactionFee; loop @@ -1021,9 +1025,9 @@ bool CWallet::CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& w bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) { CRITICAL_BLOCK(cs_main) + CRITICAL_BLOCK(cs_wallet) { printf("CommitTransaction:\n%s", wtxNew.ToString().c_str()); - CRITICAL_BLOCK(cs_mapWallet) { // This is only to keep the database open to defeat the auto-flush for the // duration of this scope. This is the only place where this optimization @@ -1053,8 +1057,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) } // Track how many getdata requests our transaction gets - CRITICAL_BLOCK(cs_mapRequestCount) - mapRequestCount[wtxNew.GetHash()] = 0; + mapRequestCount[wtxNew.GetHash()] = 0; // Broadcast if (!wtxNew.AcceptToMemoryPool()) @@ -1072,29 +1075,26 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) -// requires cs_main lock string CWallet::SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee) { CReserveKey reservekey(this); int64 nFeeRequired; - CRITICAL_BLOCK(cs_vMasterKey) + + if (IsLocked()) { - if (IsLocked()) - { - string strError = _("Error: Wallet locked, unable to create transaction "); - printf("SendMoney() : %s", strError.c_str()); - return strError; - } - if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired)) - { - string strError; - if (nValue + nFeeRequired > GetBalance()) - strError = strprintf(_("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds "), FormatMoney(nFeeRequired).c_str()); - else - strError = _("Error: Transaction creation failed "); - printf("SendMoney() : %s", strError.c_str()); - return strError; - } + string strError = _("Error: Wallet locked, unable to create transaction "); + printf("SendMoney() : %s", strError.c_str()); + return strError; + } + if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired)) + { + string strError; + if (nValue + nFeeRequired > GetBalance()) + strError = strprintf(_("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds "), FormatMoney(nFeeRequired).c_str()); + else + strError = _("Error: Transaction creation failed "); + printf("SendMoney() : %s", strError.c_str()); + return strError; } if (fAskFee && !ThreadSafeAskFee(nFeeRequired, _("Sending..."), NULL)) @@ -1109,7 +1109,6 @@ string CWallet::SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, -// requires cs_main lock string CWallet::SendMoneyToBitcoinAddress(const CBitcoinAddress& address, int64 nValue, CWalletTx& wtxNew, bool fAskFee) { // Check amount @@ -1172,7 +1171,7 @@ bool CWallet::DelAddressBookName(const CBitcoinAddress& address) void CWallet::PrintWallet(const CBlock& block) { - CRITICAL_BLOCK(cs_mapWallet) + CRITICAL_BLOCK(cs_wallet) { if (mapWallet.count(block.vtx[0].GetHash())) { @@ -1185,7 +1184,7 @@ void CWallet::PrintWallet(const CBlock& block) bool CWallet::GetTransaction(const uint256 &hashTx, CWalletTx& wtx) { - CRITICAL_BLOCK(cs_mapWallet) + CRITICAL_BLOCK(cs_wallet) { map::iterator mi = mapWallet.find(hashTx); if (mi != mapWallet.end()) @@ -1218,10 +1217,7 @@ bool GetWalletFile(CWallet* pwallet, string &strWalletFileOut) bool CWallet::TopUpKeyPool() { - CRITICAL_BLOCK(cs_main) - CRITICAL_BLOCK(cs_mapWallet) - CRITICAL_BLOCK(cs_setKeyPool) - CRITICAL_BLOCK(cs_vMasterKey) + CRITICAL_BLOCK(cs_wallet) { if (IsLocked()) return false; @@ -1248,9 +1244,7 @@ void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool) { nIndex = -1; keypool.vchPubKey.clear(); - CRITICAL_BLOCK(cs_main) - CRITICAL_BLOCK(cs_mapWallet) - CRITICAL_BLOCK(cs_setKeyPool) + CRITICAL_BLOCK(cs_wallet) { if (!IsLocked()) TopUpKeyPool(); @@ -1278,10 +1272,7 @@ void CWallet::KeepKey(int64 nIndex) if (fFileBacked) { CWalletDB walletdb(strWalletFile); - CRITICAL_BLOCK(cs_main) - { - walletdb.ErasePool(nIndex); - } + walletdb.ErasePool(nIndex); } printf("keypool keep %"PRI64d"\n", nIndex); } @@ -1289,7 +1280,7 @@ void CWallet::KeepKey(int64 nIndex) void CWallet::ReturnKey(int64 nIndex) { // Return to key pool - CRITICAL_BLOCK(cs_setKeyPool) + CRITICAL_BLOCK(cs_wallet) setKeyPool.insert(nIndex); printf("keypool return %"PRI64d"\n", nIndex); } diff --git a/src/wallet.h b/src/wallet.h index 499f2a63a..032284dd3 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -20,14 +20,14 @@ private: bool SelectCoins(int64 nTargetValue, std::set >& setCoinsRet, int64& nValueRet) const; CWalletDB *pwalletdbEncryption; - CCriticalSection cs_pwalletdbEncryption; public: + mutable CCriticalSection cs_wallet; + bool fFileBacked; std::string strWalletFile; std::set setKeyPool; - CCriticalSection cs_setKeyPool; typedef std::map MasterKeyMap; MasterKeyMap mapMasterKeys; @@ -47,15 +47,12 @@ public: pwalletdbEncryption = NULL; } - mutable CCriticalSection cs_mapWallet; std::map mapWallet; std::vector vWalletUpdated; std::map mapRequestCount; - mutable CCriticalSection cs_mapRequestCount; std::map mapAddressBook; - mutable CCriticalSection cs_mapAddressBook; std::vector vchDefaultKey; @@ -107,7 +104,7 @@ public: { CBitcoinAddress address; if (ExtractAddress(txout.scriptPubKey, this, address)) - CRITICAL_BLOCK(cs_mapAddressBook) + CRITICAL_BLOCK(cs_wallet) if (!mapAddressBook.count(address)) return true; return false; @@ -171,15 +168,13 @@ public: int LoadWallet(bool& fFirstRunRet); // bool BackupWallet(const std::string& strDest); - // requires cs_mapAddressBook lock bool SetAddressBookName(const CBitcoinAddress& address, const std::string& strName); - // requires cs_mapAddressBook lock bool DelAddressBookName(const CBitcoinAddress& address); void UpdatedTransaction(const uint256 &hashTx) { - CRITICAL_BLOCK(cs_mapWallet) + CRITICAL_BLOCK(cs_wallet) vWalletUpdated.push_back(hashTx); } @@ -187,7 +182,7 @@ public: void Inventory(const uint256 &hash) { - CRITICAL_BLOCK(cs_mapRequestCount) + CRITICAL_BLOCK(cs_wallet) { std::map::iterator mi = mapRequestCount.find(hash); if (mi != mapRequestCount.end()) From 471426fb3b2c2fa37640c03819c4f7be69ba8301 Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Wed, 31 Aug 2011 12:27:19 -0400 Subject: [PATCH 20/29] Fixed potential deadlocks in GUI code. Also changed semantics of CWalletTx::GetTxTime(); now always returns the time the transaction was received by this node, not the average block time. And added information about -DDEBUG_LOCKORDER to coding.txt. --- doc/coding.txt | 44 ++++++ src/ui.cpp | 358 ++++++++++++++++++++++++------------------------- src/wallet.cpp | 16 --- 3 files changed, 223 insertions(+), 195 deletions(-) diff --git a/doc/coding.txt b/doc/coding.txt index 470747669..ec31ccded 100644 --- a/doc/coding.txt +++ b/doc/coding.txt @@ -39,3 +39,47 @@ v vector or similar list objects map map or multimap set set or multiset bn CBigNum + +------------------------- +Locking/mutex usage notes + +The code is multi-threaded, and uses mutexes and the CRITICAL_BLOCK/TRY_CRITICAL_BLOCK macros to protect data structures. + +Deadlocks due to inconsistent lock ordering (thread 1 locks cs_main and then cs_wallet, while thread 2 locks them in the opposite order: result, deadlock as each waits for the other to release its lock) are a problem. Compile with -DDEBUG_LOCKORDER to get lock order inconsistencies reported in the debug.log file. + +Re-architecting the core code so there are better-defined interfaces between the various components is a goal, with any necessary locking done by the components (e.g. see the self-contained CKeyStore class and its cs_KeyStore lock for example). + +------- +Threads + +StartNode : Starts other threads. + +ThreadGetMyExternalIP : Determines outside-the-firewall IP address, sends addr message to connected peers when it determines it. + +ThreadIRCSeed : Joins IRC bootstrapping channel, watching for new peers and advertising this node's IP address. + +ThreadSocketHandler : Sends/Receives data from peers on port 8333. + +ThreadMessageHandler : Higher-level message handling (sending and receiving). + +ThreadOpenConnections : Initiates new connections to peers. + +ThreadTopUpKeyPool : replenishes the keystore's keypool. + +ThreadCleanWalletPassphrase : re-locks an encrypted wallet after user has unlocked it for a period of time. + +SendingDialogStartTransfer : used by pay-via-ip-address code (obsolete) + +ThreadDelayedRepaint : repaint the gui + +ThreadFlushWalletDB : Close the wallet.dat file if it hasn't been used in 500ms. + +ThreadRPCServer : Remote procedure call handler, listens on port 8332 for connections and services them. + +ThreadBitcoinMiner : Generates bitcoins + +ThreadMapPort : Universal plug-and-play startup/shutdown + +Shutdown : Does an orderly shutdown of everything + +ExitTimeout : Windows-only, sleeps 5 seconds then exits application diff --git a/src/ui.cpp b/src/ui.cpp index 867c9c0a0..5ca666192 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -708,7 +708,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) CBitcoinAddress address; if (ExtractAddress(txout.scriptPubKey, pwalletMain, address)) { - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) + CRITICAL_BLOCK(pwalletMain->cs_wallet) { //strDescription += _("Received payment to "); //strDescription += _("Received with address "); @@ -792,7 +792,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) } string strDescription = _("To: "); - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) + CRITICAL_BLOCK(pwalletMain->cs_wallet) if (pwalletMain->mapAddressBook.count(address) && !pwalletMain->mapAddressBook[address].empty()) strDescription += pwalletMain->mapAddressBook[address] + " "; strDescription += strAddress; @@ -1032,6 +1032,7 @@ void MainFrameRepaint() printf("MainFrameRepaint\n"); wxPaintEvent event; pframeMain->fRefresh = true; + pframeMain->fRefreshListCtrl = true; pframeMain->GetEventHandler()->AddPendingEvent(event); } } @@ -1247,83 +1248,80 @@ void CMainFrame::OnMenuOptionsChangeWalletPassphrase(wxCommandEvent& event) strOldWalletPass = wxGetPasswordFromUser(_("Enter the current passphrase to the wallet."), _("Passphrase")).ToStdString(); - CRITICAL_BLOCK(pwalletMain->cs_vMasterKey) - { - bool fWasLocked = pwalletMain->IsLocked(); - pwalletMain->Lock(); + bool fWasLocked = pwalletMain->IsLocked(); + pwalletMain->Lock(); - if (!strOldWalletPass.size() || !pwalletMain->Unlock(strOldWalletPass)) - { - fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0'); - munlock(&strOldWalletPass[0], strOldWalletPass.capacity()); - wxMessageBox(_("The passphrase entered for the wallet decryption was incorrect."), "Bitcoin", wxOK | wxICON_ERROR); - return; - } + if (!strOldWalletPass.size() || !pwalletMain->Unlock(strOldWalletPass)) + { + fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0'); + munlock(&strOldWalletPass[0], strOldWalletPass.capacity()); + wxMessageBox(_("The passphrase entered for the wallet decryption was incorrect."), "Bitcoin", wxOK | wxICON_ERROR); + return; + } - if (fWasLocked) - pwalletMain->Lock(); + if (fWasLocked) + pwalletMain->Lock(); - string strNewWalletPass; - strNewWalletPass.reserve(100); - mlock(&strNewWalletPass[0], strNewWalletPass.capacity()); + string strNewWalletPass; + strNewWalletPass.reserve(100); + mlock(&strNewWalletPass[0], strNewWalletPass.capacity()); - // obtain new wallet encrypt/decrypt key, from passphrase - // Note that the passphrase is not mlock()d during this entry and could potentially - // be obtained from disk long after bitcoin has run. - strNewWalletPass = wxGetPasswordFromUser(_("Enter the new passphrase for the wallet."), - _("Passphrase")).ToStdString(); + // obtain new wallet encrypt/decrypt key, from passphrase + // Note that the passphrase is not mlock()d during this entry and could potentially + // be obtained from disk long after bitcoin has run. + strNewWalletPass = wxGetPasswordFromUser(_("Enter the new passphrase for the wallet."), + _("Passphrase")).ToStdString(); - if (!strNewWalletPass.size()) - { - fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0'); - fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0'); - munlock(&strOldWalletPass[0], strOldWalletPass.capacity()); - munlock(&strNewWalletPass[0], strNewWalletPass.capacity()); - wxMessageBox(_("Error: The supplied passphrase was too short."), "Bitcoin", wxOK | wxICON_ERROR); - return; - } + if (!strNewWalletPass.size()) + { + fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0'); + fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0'); + munlock(&strOldWalletPass[0], strOldWalletPass.capacity()); + munlock(&strNewWalletPass[0], strNewWalletPass.capacity()); + wxMessageBox(_("Error: The supplied passphrase was too short."), "Bitcoin", wxOK | wxICON_ERROR); + return; + } - string strNewWalletPassTest; - strNewWalletPassTest.reserve(100); - mlock(&strNewWalletPassTest[0], strNewWalletPassTest.capacity()); + string strNewWalletPassTest; + strNewWalletPassTest.reserve(100); + mlock(&strNewWalletPassTest[0], strNewWalletPassTest.capacity()); - // obtain new wallet encrypt/decrypt key, from passphrase - // Note that the passphrase is not mlock()d during this entry and could potentially - // be obtained from disk long after bitcoin has run. - strNewWalletPassTest = wxGetPasswordFromUser(_("Re-enter the new passphrase for the wallet."), - _("Passphrase")).ToStdString(); + // obtain new wallet encrypt/decrypt key, from passphrase + // Note that the passphrase is not mlock()d during this entry and could potentially + // be obtained from disk long after bitcoin has run. + strNewWalletPassTest = wxGetPasswordFromUser(_("Re-enter the new passphrase for the wallet."), + _("Passphrase")).ToStdString(); - if (strNewWalletPassTest != strNewWalletPass) - { - fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0'); - fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0'); - fill(strNewWalletPassTest.begin(), strNewWalletPassTest.end(), '\0'); - munlock(&strOldWalletPass[0], strOldWalletPass.capacity()); - munlock(&strNewWalletPass[0], strNewWalletPass.capacity()); - munlock(&strNewWalletPassTest[0], strNewWalletPassTest.capacity()); - wxMessageBox(_("Error: the supplied passphrases didn't match."), "Bitcoin", wxOK | wxICON_ERROR); - return; - } + if (strNewWalletPassTest != strNewWalletPass) + { + fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0'); + fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0'); + fill(strNewWalletPassTest.begin(), strNewWalletPassTest.end(), '\0'); + munlock(&strOldWalletPass[0], strOldWalletPass.capacity()); + munlock(&strNewWalletPass[0], strNewWalletPass.capacity()); + munlock(&strNewWalletPassTest[0], strNewWalletPassTest.capacity()); + wxMessageBox(_("Error: the supplied passphrases didn't match."), "Bitcoin", wxOK | wxICON_ERROR); + return; + } - if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass)) - { - fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0'); - fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0'); - fill(strNewWalletPassTest.begin(), strNewWalletPassTest.end(), '\0'); - munlock(&strOldWalletPass[0], strOldWalletPass.capacity()); - munlock(&strNewWalletPass[0], strNewWalletPass.capacity()); - munlock(&strNewWalletPassTest[0], strNewWalletPassTest.capacity()); - wxMessageBox(_("The passphrase entered for the wallet decryption was incorrect."), "Bitcoin", wxOK | wxICON_ERROR); - return; - } + if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass)) + { fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0'); fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0'); fill(strNewWalletPassTest.begin(), strNewWalletPassTest.end(), '\0'); munlock(&strOldWalletPass[0], strOldWalletPass.capacity()); munlock(&strNewWalletPass[0], strNewWalletPass.capacity()); munlock(&strNewWalletPassTest[0], strNewWalletPassTest.capacity()); - wxMessageBox(_("Wallet Passphrase Changed."), "Bitcoin"); + wxMessageBox(_("The passphrase entered for the wallet decryption was incorrect."), "Bitcoin", wxOK | wxICON_ERROR); + return; } + fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0'); + fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0'); + fill(strNewWalletPassTest.begin(), strNewWalletPassTest.end(), '\0'); + munlock(&strOldWalletPass[0], strOldWalletPass.capacity()); + munlock(&strNewWalletPass[0], strNewWalletPass.capacity()); + munlock(&strNewWalletPassTest[0], strNewWalletPassTest.capacity()); + wxMessageBox(_("Wallet Passphrase Changed."), "Bitcoin"); } void CMainFrame::OnMenuOptionsOptions(wxCommandEvent& event) @@ -1387,21 +1385,19 @@ void CMainFrame::OnButtonNew(wxCommandEvent& event) string strName = dialog.GetValue(); string strAddress; - CRITICAL_BLOCK(pwalletMain->cs_vMasterKey) - { - bool fWasLocked = pwalletMain->IsLocked(); - if (!GetWalletPassphrase()) - return; - // Generate new key - strAddress = CBitcoinAddress(pwalletMain->GetOrReuseKeyFromPool()).ToString(); + bool fWasLocked = pwalletMain->IsLocked(); + if (!GetWalletPassphrase()) + return; - if (fWasLocked) - pwalletMain->Lock(); - } + // Generate new key + strAddress = CBitcoinAddress(pwalletMain->GetOrReuseKeyFromPool()).ToString(); + + if (fWasLocked) + pwalletMain->Lock(); // Save - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) + CRITICAL_BLOCK(pwalletMain->cs_wallet) pwalletMain->SetAddressBookName(strAddress, strName); SetDefaultReceivingAddress(strAddress); } @@ -1451,7 +1447,7 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails #ifdef __WXMSW__ SetSize(nScaleX * GetSize().GetWidth(), nScaleY * GetSize().GetHeight()); #endif - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) + CRITICAL_BLOCK(pwalletMain->cs_wallet) { string strHTML; strHTML.reserve(4000); @@ -2160,38 +2156,39 @@ void CSendDialog::OnButtonSend(wxCommandEvent& event) if (fBitcoinAddress) { + bool fWasLocked = pwalletMain->IsLocked(); + if (!GetWalletPassphrase()) + return; + + string strError; CRITICAL_BLOCK(cs_main) - CRITICAL_BLOCK(pwalletMain->cs_vMasterKey) + CRITICAL_BLOCK(pwalletMain->cs_wallet) { - bool fWasLocked = pwalletMain->IsLocked(); - if (!GetWalletPassphrase()) - return; - // Send to bitcoin address CScript scriptPubKey; scriptPubKey.SetBitcoinAddress(address); - string strError = pwalletMain->SendMoney(scriptPubKey, nValue, wtx, true); - if (strError == "") - wxMessageBox(_("Payment sent "), _("Sending...")); - else if (strError == "ABORTED") - { - if (fWasLocked) - pwalletMain->Lock(); - return; // leave send dialog open - } - else - { - wxMessageBox(strError + " ", _("Sending...")); - EndModal(false); - if (fWasLocked) - pwalletMain->Lock(); - return; - } - + strError = pwalletMain->SendMoney(scriptPubKey, nValue, wtx, true); + } + if (strError == "") + wxMessageBox(_("Payment sent "), _("Sending...")); + else if (strError == "ABORTED") + { if (fWasLocked) pwalletMain->Lock(); - } + return; // leave send dialog open + } + else + { + wxMessageBox(strError + " ", _("Sending...")); + EndModal(false); + if (fWasLocked) + pwalletMain->Lock(); + return; + } + + if (fWasLocked) + pwalletMain->Lock(); } else { @@ -2212,7 +2209,7 @@ void CSendDialog::OnButtonSend(wxCommandEvent& event) return; } - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) + CRITICAL_BLOCK(pwalletMain->cs_wallet) if (!pwalletMain->mapAddressBook.count(address)) pwalletMain->SetAddressBookName(strAddress, ""); @@ -2464,83 +2461,89 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) return; } - CRITICAL_BLOCK(cs_main) + // Pay + if (!Status(_("Creating transaction..."))) + return; + if (nPrice + nTransactionFee > pwalletMain->GetBalance()) { - // Pay - if (!Status(_("Creating transaction..."))) - return; - if (nPrice + nTransactionFee > pwalletMain->GetBalance()) - { - Error(_("Insufficient funds")); - return; - } + Error(_("Insufficient funds")); + return; + } - CReserveKey reservekey(pwalletMain); - int64 nFeeRequired; - CRITICAL_BLOCK(pwalletMain->cs_vMasterKey) - { - bool fWasLocked = pwalletMain->IsLocked(); - if (!GetWalletPassphrase()) - return; + CReserveKey reservekey(pwalletMain); + int64 nFeeRequired; + bool fWasLocked = pwalletMain->IsLocked(); + if (!GetWalletPassphrase()) + return; - if (!pwalletMain->CreateTransaction(scriptPubKey, nPrice, wtx, reservekey, nFeeRequired)) - { - if (nPrice + nFeeRequired > pwalletMain->GetBalance()) - Error(strprintf(_("This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds"), FormatMoney(nFeeRequired).c_str())); - else - Error(_("Transaction creation failed")); - return; - } + bool fTxCreated = false; + CRITICAL_BLOCK(cs_main) + CRITICAL_BLOCK(pwalletMain->cs_wallet) + { + fTxCreated = pwalletMain->CreateTransaction(scriptPubKey, nPrice, wtx, reservekey, nFeeRequired); + } + if (!fTxCreated) + { + if (nPrice + nFeeRequired > pwalletMain->GetBalance()) + Error(strprintf(_("This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds"), FormatMoney(nFeeRequired).c_str())); + else + Error(_("Transaction creation failed")); + return; + } - if (fWasLocked) - pwalletMain->Lock(); - } + if (fWasLocked) + pwalletMain->Lock(); - // Transaction fee - if (!ThreadSafeAskFee(nFeeRequired, _("Sending..."), this)) - { - Error(_("Transaction aborted")); - return; - } + // Transaction fee + if (!ThreadSafeAskFee(nFeeRequired, _("Sending..."), this)) + { + Error(_("Transaction aborted")); + return; + } - // Make sure we're still connected - CNode* pnode = ConnectNode(addr, 2 * 60 * 60); - if (!pnode) - { - Error(_("Lost connection, transaction cancelled")); - return; - } + // Make sure we're still connected + CNode* pnode = ConnectNode(addr, 2 * 60 * 60); + if (!pnode) + { + Error(_("Lost connection, transaction cancelled")); + return; + } - // Last chance to cancel - Sleep(50); + // Last chance to cancel + Sleep(50); + if (!Status()) + return; + fCanCancel = false; + if (fAbort) + { + fCanCancel = true; if (!Status()) return; fCanCancel = false; - if (fAbort) - { - fCanCancel = true; - if (!Status()) - return; - fCanCancel = false; - } - if (!Status(_("Sending payment..."))) - return; + } + if (!Status(_("Sending payment..."))) + return; - // Commit - if (!pwalletMain->CommitTransaction(wtx, reservekey)) - { - 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.")); - return; - } + // Commit + bool fTxCommitted = false; + CRITICAL_BLOCK(cs_main) + CRITICAL_BLOCK(pwalletMain->cs_wallet) + { + fTxCommitted = pwalletMain->CommitTransaction(wtx, reservekey); + } + if (!fTxCommitted) + { + 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.")); + return; + } - // Send payment tx to seller, with response going to OnReply3 via event handler - CWalletTx wtxSend = wtx; - wtxSend.fFromMe = false; - pnode->PushRequest("submitorder", wtxSend, SendingDialogOnReply3, this); + // Send payment tx to seller, with response going to OnReply3 via event handler + CWalletTx wtxSend = wtx; + wtxSend.fFromMe = false; + pnode->PushRequest("submitorder", wtxSend, SendingDialogOnReply3, this); - Status(_("Waiting for confirmation...")); - MainFrameRepaint(); - } + Status(_("Waiting for confirmation...")); + MainFrameRepaint(); } void SendingDialogOnReply3(void* parg, CDataStream& vRecv) @@ -2621,7 +2624,7 @@ CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInit m_listCtrlReceiving->SetFocus(); // Fill listctrl with address book data - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) + CRITICAL_BLOCK(pwalletMain->cs_wallet) { string strDefaultReceiving = (string)pframeMain->m_textCtrlAddress->GetValue(); BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook) @@ -2682,7 +2685,7 @@ void CAddressBookDialog::OnListEndLabelEdit(wxListEvent& event) if (event.IsEditCancelled()) return; string strAddress = (string)GetItemText(m_listCtrl, event.GetIndex(), 1); - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) + CRITICAL_BLOCK(pwalletMain->cs_wallet) pwalletMain->SetAddressBookName(strAddress, string(event.GetText())); pframeMain->RefreshListCtrl(); } @@ -2718,7 +2721,7 @@ void CAddressBookDialog::OnButtonDelete(wxCommandEvent& event) if (m_listCtrl->GetItemState(nIndex, wxLIST_STATE_SELECTED)) { string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1); - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) + CRITICAL_BLOCK(pwalletMain->cs_wallet) pwalletMain->DelAddressBookName(strAddress); m_listCtrl->DeleteItem(nIndex); } @@ -2778,7 +2781,7 @@ void CAddressBookDialog::OnButtonEdit(wxCommandEvent& event) } // Write back - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) + CRITICAL_BLOCK(pwalletMain->cs_wallet) { if (strAddress != strAddressOrg) pwalletMain->DelAddressBookName(strAddressOrg); @@ -2818,22 +2821,19 @@ void CAddressBookDialog::OnButtonNew(wxCommandEvent& event) return; strName = dialog.GetValue(); - CRITICAL_BLOCK(pwalletMain->cs_vMasterKey) - { - bool fWasLocked = pwalletMain->IsLocked(); - if (!GetWalletPassphrase()) - return; + bool fWasLocked = pwalletMain->IsLocked(); + if (!GetWalletPassphrase()) + return; - // Generate new key - strAddress = CBitcoinAddress(pwalletMain->GetOrReuseKeyFromPool()).ToString(); + // Generate new key + strAddress = CBitcoinAddress(pwalletMain->GetOrReuseKeyFromPool()).ToString(); - if (fWasLocked) - pwalletMain->Lock(); - } + if (fWasLocked) + pwalletMain->Lock(); } // Add to list and select it - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) + CRITICAL_BLOCK(pwalletMain->cs_wallet) pwalletMain->SetAddressBookName(strAddress, strName); int nIndex = InsertLine(m_listCtrl, strName, strAddress); SetSelection(m_listCtrl, nIndex); diff --git a/src/wallet.cpp b/src/wallet.cpp index 745fbefdb..1daec98d3 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -353,22 +353,6 @@ int64 CWallet::GetDebit(const CTxIn &txin) const int64 CWalletTx::GetTxTime() const { - CRITICAL_BLOCK(cs_main) - { - if (!fTimeReceivedIsTxTime && hashBlock != 0) - { - // If we did not receive the transaction directly, we rely on the block's - // time to figure out when it happened. We use the median over a range - // of blocks to try to filter out inaccurate block times. - map::iterator mi = mapBlockIndex.find(hashBlock); - if (mi != mapBlockIndex.end()) - { - CBlockIndex* pindex = (*mi).second; - if (pindex) - return pindex->GetMedianTime(); - } - } - } return nTimeReceived; } From 541e585d8eeb9b9c981589d2f8c47208f9d4e072 Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Wed, 31 Aug 2011 14:28:14 -0300 Subject: [PATCH 21/29] Fix typo ("you own security") --- doc/README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/README b/doc/README index 831d66069..763fc415b 100644 --- a/doc/README +++ b/doc/README @@ -57,7 +57,7 @@ If everything goes fine, delete the backup and enjoy your encrypted wallet. Note that once you encrypt your wallet, you will never be able to go back to a version of the Bitcoin client older than 0.4. -Keep in mind that you are always responsible for you own security. +Keep in mind that you are always responsible for your own security. All it takes is a slightly more advanced wallet-stealing trojan which installs a keylogger to steal your wallet passphrase as you enter it in addition to your wallet file and you have lost all your Bitcoins. From e3c26b2573c75850827558daf5f04594c1360296 Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Wed, 31 Aug 2011 14:00:41 -0400 Subject: [PATCH 22/29] SetCrypted() obtains keystore lock, to be safe. --- src/keystore.cpp | 13 +++++++++++++ src/keystore.h | 10 +--------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/keystore.cpp b/src/keystore.cpp index 5bf919cb8..68f57e7e0 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -33,6 +33,19 @@ bool CBasicKeyStore::AddKey(const CKey& key) return true; } +bool CCryptoKeyStore::SetCrypted() +{ + CRITICAL_BLOCK(cs_KeyStore) + { + if (fUseCrypto) + return true; + if (!mapKeys.empty()) + return false; + fUseCrypto = true; + } + return true; +} + std::vector CCryptoKeyStore::GenerateNewKey() { RandAddSeedPerfmon(); diff --git a/src/keystore.h b/src/keystore.h index d1e4985d5..bbfac83d1 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -65,15 +65,7 @@ private: bool fUseCrypto; protected: - bool SetCrypted() - { - if (fUseCrypto) - return true; - if (!mapKeys.empty()) - return false; - fUseCrypto = true; - return true; - } + bool SetCrypted(); // will encrypt previously unencrypted keys bool EncryptKeys(CKeyingMaterial& vMasterKeyIn); From 7db3b75b3e38c2088596f49cb51fe1c9c7e8b433 Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Fri, 12 Aug 2011 16:32:07 -0400 Subject: [PATCH 23/29] Logic running with -keypool=0 was wrong (empty keys were being returned). Fixes #445 Renames GetOrReuseKeyFromKeyPool to GetKeyFromPool, with fAllowReuse arg and bool result. --- src/main.cpp | 2 +- src/rpc.cpp | 22 +++++++++------------- src/ui.cpp | 8 ++++++-- src/wallet.cpp | 31 ++++++++++++++++++++++++------- src/wallet.h | 2 +- 5 files changed, 41 insertions(+), 24 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 36fdaa72f..203b8d5f9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2183,7 +2183,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) // Keep giving the same key to the same ip until they use it if (!mapReuseKey.count(pfrom->addr.ip)) - mapReuseKey[pfrom->addr.ip] = pwalletMain->GetOrReuseKeyFromPool(); + pwalletMain->GetKeyFromPool(mapReuseKey[pfrom->addr.ip], true); // Send back approval of order and pubkey to use CScript scriptPubKey; diff --git a/src/rpc.cpp b/src/rpc.cpp index 5eb5669ac..161606af3 100644 --- a/src/rpc.cpp +++ b/src/rpc.cpp @@ -331,21 +331,20 @@ Value getnewaddress(const Array& params, bool fHelp) "If [account] is specified (recommended), it is added to the address book " "so payments received with the address will be credited to [account]."); - if (!pwalletMain->IsLocked()) - pwalletMain->TopUpKeyPool(); - - if (pwalletMain->GetKeyPoolSize() < 1) - throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first"); - // Parse the account first so we don't generate a key if there's an error string strAccount; if (params.size() > 0) strAccount = AccountFromValue(params[0]); + if (!pwalletMain->IsLocked()) + pwalletMain->TopUpKeyPool(); + // Generate a new key that is added to wallet - CBitcoinAddress address(pwalletMain->GetOrReuseKeyFromPool()); + std::vector newKey; + if (!pwalletMain->GetKeyFromPool(newKey, false)) + throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first"); + CBitcoinAddress address(newKey); - // This could be done in the same main CS as GetKeyFromKeyPool. pwalletMain->SetAddressBookName(address, strAccount); return address.ToString(); @@ -382,12 +381,9 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) { if (pwalletMain->GetKeyPoolSize() < 1) { - if (bKeyUsed || bForceNew) + if (!pwalletMain->GetKeyFromPool(account.vchPubKey, false)) throw JSONRPCError(-12, "Error: Keypool ran out, please call topupkeypool first"); - } - else - { - account.vchPubKey = pwalletMain->GetOrReuseKeyFromPool(); + pwalletMain->SetAddressBookName(CBitcoinAddress(account.vchPubKey), strAccount); walletdb.WriteAccount(strAccount, account); } diff --git a/src/ui.cpp b/src/ui.cpp index 5ca666192..c820cf7df 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -1391,7 +1391,9 @@ void CMainFrame::OnButtonNew(wxCommandEvent& event) return; // Generate new key - strAddress = CBitcoinAddress(pwalletMain->GetOrReuseKeyFromPool()).ToString(); + std::vector newKey; + pwalletMain->GetKeyFromPool(newKey, true); + strAddress = CBitcoinAddress(newKey).ToString(); if (fWasLocked) pwalletMain->Lock(); @@ -2826,7 +2828,9 @@ void CAddressBookDialog::OnButtonNew(wxCommandEvent& event) return; // Generate new key - strAddress = CBitcoinAddress(pwalletMain->GetOrReuseKeyFromPool()).ToString(); + std::vector newKey; + pwalletMain->GetKeyFromPool(newKey, true); + strAddress = CBitcoinAddress(newKey).ToString(); if (fWasLocked) pwalletMain->Lock(); diff --git a/src/wallet.cpp b/src/wallet.cpp index 1daec98d3..e861416e5 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -268,8 +268,12 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn) { if (txout.scriptPubKey == scriptDefaultKey) { - SetDefaultKey(GetOrReuseKeyFromPool()); - SetAddressBookName(CBitcoinAddress(vchDefaultKey), ""); + std::vector newDefaultKey; + if (GetKeyFromPool(newDefaultKey, false)) + { + SetDefaultKey(newDefaultKey); + SetAddressBookName(CBitcoinAddress(vchDefaultKey), ""); + } } } @@ -1126,7 +1130,10 @@ int CWallet::LoadWallet(bool& fFirstRunRet) // Create new keyUser and set as default key RandAddSeedPerfmon(); - SetDefaultKey(GetOrReuseKeyFromPool()); + std::vector newDefaultKey; + if (!GetKeyFromPool(newDefaultKey, false)) + return DB_LOAD_FAIL; + SetDefaultKey(newDefaultKey); if (!SetAddressBookName(CBitcoinAddress(vchDefaultKey), "")) return DB_LOAD_FAIL; } @@ -1269,15 +1276,25 @@ void CWallet::ReturnKey(int64 nIndex) printf("keypool return %"PRI64d"\n", nIndex); } -vector CWallet::GetOrReuseKeyFromPool() +bool CWallet::GetKeyFromPool(vector& result, bool fAllowReuse) { int64 nIndex = 0; CKeyPool keypool; ReserveKeyFromKeyPool(nIndex, keypool); - if(nIndex == -1) - return vchDefaultKey; + if (nIndex == -1) + { + if (fAllowReuse && !vchDefaultKey.empty()) + { + result = vchDefaultKey; + return true; + } + if (IsLocked()) return false; + result = GenerateNewKey(); + return true; + } KeepKey(nIndex); - return keypool.vchPubKey; + result = keypool.vchPubKey; + return true; } int64 CWallet::GetOldestKeyPoolTime() diff --git a/src/wallet.h b/src/wallet.h index 032284dd3..1dd2e5126 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -85,7 +85,7 @@ public: void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool); void KeepKey(int64 nIndex); void ReturnKey(int64 nIndex); - std::vector GetOrReuseKeyFromPool(); + bool GetKeyFromPool(std::vector &key, bool fAllowReuse=true); int64 GetOldestKeyPoolTime(); bool IsMine(const CTxIn& txin) const; From 123e5bd9982376b5feba8c32c67ff0286697a867 Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Mon, 15 Aug 2011 11:07:25 -0400 Subject: [PATCH 24/29] Fix RPC call name in error message. --- src/rpc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpc.cpp b/src/rpc.cpp index 161606af3..ec2bb2a97 100644 --- a/src/rpc.cpp +++ b/src/rpc.cpp @@ -382,7 +382,7 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) if (pwalletMain->GetKeyPoolSize() < 1) { if (!pwalletMain->GetKeyFromPool(account.vchPubKey, false)) - throw JSONRPCError(-12, "Error: Keypool ran out, please call topupkeypool first"); + throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first"); pwalletMain->SetAddressBookName(CBitcoinAddress(account.vchPubKey), strAccount); walletdb.WriteAccount(strAccount, account); From ed02c95d505ce48451b600ff40720841a000fd50 Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Thu, 1 Sep 2011 10:58:08 -0400 Subject: [PATCH 25/29] obtain cs_wallet mutex to protect vchDefaultKey --- src/wallet.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/wallet.cpp b/src/wallet.cpp index e861416e5..8bbb80cf2 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1280,20 +1280,23 @@ bool CWallet::GetKeyFromPool(vector& result, bool fAllowReuse) { int64 nIndex = 0; CKeyPool keypool; - ReserveKeyFromKeyPool(nIndex, keypool); - if (nIndex == -1) + CRITICAL_BLOCK(cs_wallet) { - if (fAllowReuse && !vchDefaultKey.empty()) + ReserveKeyFromKeyPool(nIndex, keypool); + if (nIndex == -1) { - result = vchDefaultKey; + if (fAllowReuse && !vchDefaultKey.empty()) + { + result = vchDefaultKey; + return true; + } + if (IsLocked()) return false; + result = GenerateNewKey(); return true; } - if (IsLocked()) return false; - result = GenerateNewKey(); - return true; + KeepKey(nIndex); + result = keypool.vchPubKey; } - KeepKey(nIndex); - result = keypool.vchPubKey; return true; } From 36d9b2311dcb7401ea0d3deda636bc50f135c522 Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Thu, 1 Sep 2011 15:44:39 -0400 Subject: [PATCH 26/29] Fixed regression I introduced: wallets with lots of transactions were unusable in GUI. --- src/ui.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ui.cpp b/src/ui.cpp index c820cf7df..198a27209 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -1032,7 +1032,6 @@ void MainFrameRepaint() printf("MainFrameRepaint\n"); wxPaintEvent event; pframeMain->fRefresh = true; - pframeMain->fRefreshListCtrl = true; pframeMain->GetEventHandler()->AddPendingEvent(event); } } @@ -2173,7 +2172,10 @@ void CSendDialog::OnButtonSend(wxCommandEvent& event) strError = pwalletMain->SendMoney(scriptPubKey, nValue, wtx, true); } if (strError == "") + { + pframeMain->RefreshListCtrl(); wxMessageBox(_("Payment sent "), _("Sending...")); + } else if (strError == "ABORTED") { if (fWasLocked) From 2f4c30fd85aed8227612ee9986226850723c6860 Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Thu, 1 Sep 2011 18:40:18 -0400 Subject: [PATCH 27/29] Fix bad merge: getaccountaddress was broken for new accounts --- src/rpc.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/rpc.cpp b/src/rpc.cpp index ec2bb2a97..4f4342770 100644 --- a/src/rpc.cpp +++ b/src/rpc.cpp @@ -379,14 +379,11 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) // Generate a new key if (account.vchPubKey.empty() || bForceNew || bKeyUsed) { - if (pwalletMain->GetKeyPoolSize() < 1) - { - if (!pwalletMain->GetKeyFromPool(account.vchPubKey, false)) - throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first"); + if (!pwalletMain->GetKeyFromPool(account.vchPubKey, false)) + throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first"); - pwalletMain->SetAddressBookName(CBitcoinAddress(account.vchPubKey), strAccount); - walletdb.WriteAccount(strAccount, account); - } + pwalletMain->SetAddressBookName(CBitcoinAddress(account.vchPubKey), strAccount); + walletdb.WriteAccount(strAccount, account); } return CBitcoinAddress(account.vchPubKey); From bca179e8bd9b9d38a07c16169d70926633ab0bc9 Mon Sep 17 00:00:00 2001 From: Daniel Folkinshteyn Date: Fri, 2 Sep 2011 00:00:22 -0400 Subject: [PATCH 28/29] Update the list of seednodes. Nodes culled from MagicalTux's database of bitcoin nodes, http://dump.bitcoin.it/misc/ by version and longevity, and tested for connectivity. --- src/net.cpp | 104 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 64 insertions(+), 40 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 500d0174e..1655cfbdc 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1193,46 +1193,70 @@ void DNSAddressSeed() unsigned int pnSeed[] = { - 0x1ddb1032, 0x6242ce40, 0x52d6a445, 0x2dd7a445, 0x8a53cd47, 0x73263750, 0xda23c257, 0xecd4ed57, - 0x0a40ec59, 0x75dce160, 0x7df76791, 0x89370bad, 0xa4f214ad, 0x767700ae, 0x638b0418, 0x868a1018, - 0xcd9f332e, 0x0129653e, 0xcc92dc3e, 0x96671640, 0x56487e40, 0x5b66f440, 0xb1d01f41, 0xf1dc6041, - 0xc1d12b42, 0x86ba1243, 0x6be4df43, 0x6d4cef43, 0xd18e0644, 0x1ab0b344, 0x6584a345, 0xe7c1a445, - 0x58cea445, 0xc5daa445, 0x21dda445, 0x3d3b5346, 0x13e55347, 0x1080d24a, 0x8e611e4b, 0x81518e4b, - 0x6c839e4b, 0xe2ad0a4c, 0xfbbc0a4c, 0x7f5b6e4c, 0x7244224e, 0x1300554e, 0x20690652, 0x5a48b652, - 0x75c5c752, 0x4335cc54, 0x340fd154, 0x87c07455, 0x087b2b56, 0x8a133a57, 0xac23c257, 0x70374959, - 0xfb63d45b, 0xb9a1685c, 0x180d765c, 0x674f645d, 0x04d3495e, 0x1de44b5e, 0x4ee8a362, 0x0ded1b63, - 0xc1b04b6d, 0x8d921581, 0x97b7ea82, 0x1cf83a8e, 0x91490bad, 0x09dc75ae, 0x9a6d79ae, 0xa26d79ae, - 0x0fd08fae, 0x0f3e3fb2, 0x4f944fb2, 0xcca448b8, 0x3ecd6ab8, 0xa9d5a5bc, 0x8d0119c1, 0x045997d5, - 0xca019dd9, 0x0d526c4d, 0xabf1ba44, 0x66b1ab55, 0x1165f462, 0x3ed7cbad, 0xa38fae6e, 0x3bd2cbad, - 0xd36f0547, 0x20df7840, 0x7a337742, 0x549f8e4b, 0x9062365c, 0xd399f562, 0x2b5274a1, 0x8edfa153, - 0x3bffb347, 0x7074bf58, 0xb74fcbad, 0x5b5a795b, 0x02fa29ce, 0x5a6738d4, 0xe8a1d23e, 0xef98c445, - 0x4b0f494c, 0xa2bc1e56, 0x7694ad63, 0xa4a800c3, 0x05fda6cd, 0x9f22175e, 0x364a795b, 0x536285d5, - 0xac44c9d4, 0x0b06254d, 0x150c2fd4, 0x32a50dcc, 0xfd79ce48, 0xf15cfa53, 0x66c01e60, 0x6bc26661, - 0xc03b47ae, 0x4dda1b81, 0x3285a4c1, 0x883ca96d, 0x35d60a4c, 0xdae09744, 0x2e314d61, 0x84e247cf, - 0x6c814552, 0x3a1cc658, 0x98d8f382, 0xe584cb5b, 0x15e86057, 0x7b01504e, 0xd852dd48, 0x56382f56, - 0x0a5df454, 0xa0d18d18, 0x2e89b148, 0xa79c114c, 0xcbdcd054, 0x5523bc43, 0xa9832640, 0x8a066144, - 0x3894c3bc, 0xab76bf58, 0x6a018ac1, 0xfebf4f43, 0x2f26c658, 0x31102f4e, 0x85e929d5, 0x2a1c175e, - 0xfc6c2cd1, 0x27b04b6d, 0xdf024650, 0x161748b8, 0x28be6580, 0x57be6580, 0x1cee677a, 0xaa6bb742, - 0x9a53964b, 0x0a5a2d4d, 0x2434c658, 0x9a494f57, 0x1ebb0e48, 0xf610b85d, 0x077ecf44, 0x085128bc, - 0x5ba17a18, 0x27ca1b42, 0xf8a00b56, 0xfcd4c257, 0xcf2fc15e, 0xd897e052, 0x4cada04f, 0x2f35f6d5, - 0x382ce8c9, 0xe523984b, 0x3f946846, 0x60c8be43, 0x41da6257, 0xde0be142, 0xae8a544b, 0xeff0c254, - 0x1e0f795b, 0xaeb28890, 0xca16acd9, 0x1e47ddd8, 0x8c8c4829, 0xd27dc747, 0xd53b1663, 0x4096b163, - 0x9c8dd958, 0xcb12f860, 0x9e79305c, 0x40c1a445, 0x4a90c2bc, 0x2c3a464d, 0x2727f23c, 0x30b04b6d, - 0x59024cb8, 0xa091e6ad, 0x31b04b6d, 0xc29d46a6, 0x63934fb2, 0xd9224dbe, 0x9f5910d8, 0x7f530a6b, - 0x752e9c95, 0x65453548, 0xa484be46, 0xce5a1b59, 0x710e0718, 0x46a13d18, 0xdaaf5318, 0xc4a8ff53, - 0x87abaa52, 0xb764cf51, 0xb2025d4a, 0x6d351e41, 0xc035c33e, 0xa432c162, 0x61ef34ae, 0xd16fddbc, - 0x0870e8c1, 0x3070e8c1, 0x9c71e8c1, 0xa4992363, 0x85a1f663, 0x4184e559, 0x18d96ed8, 0x17b8dbd5, - 0x60e7cd18, 0xe5ee104c, 0xab17ac62, 0x1e786e1b, 0x5d23b762, 0xf2388fae, 0x88270360, 0x9e5b3d80, - 0x7da518b2, 0xb5613b45, 0x1ad41f3e, 0xd550854a, 0x8617e9a9, 0x925b229c, 0xf2e92542, 0x47af0544, - 0x73b5a843, 0xb9b7a0ad, 0x03a748d0, 0x0a6ff862, 0x6694df62, 0x3bfac948, 0x8e098f4f, 0x746916c3, - 0x02f38e4f, 0x40bb1243, 0x6a54d162, 0x6008414b, 0xa513794c, 0x514aa343, 0x63781747, 0xdbb6795b, - 0xed065058, 0x42d24b46, 0x1518794c, 0x9b271681, 0x73e4ffad, 0x0654784f, 0x438dc945, 0x641846a6, - 0x2d1b0944, 0x94b59148, 0x8d369558, 0xa5a97662, 0x8b705b42, 0xce9204ae, 0x8d584450, 0x2df61555, - 0xeebff943, 0x2e75fb4d, 0x3ef8fc57, 0x9921135e, 0x8e31042e, 0xb5afad43, 0x89ecedd1, 0x9cfcc047, - 0x8fcd0f4c, 0xbe49f5ad, 0x146a8d45, 0x98669ab8, 0x98d9175e, 0xd1a8e46d, 0x839a3ab8, 0x40a0016c, - 0x6d27c257, 0x977fffad, 0x7baa5d5d, 0x1213be43, 0xb167e5a9, 0x640fe8ca, 0xbc9ea655, 0x0f820a4c, - 0x0f097059, 0x69ac957c, 0x366d8453, 0xb1ba2844, 0x8857f081, 0x70b5be63, 0xc545454b, 0xaf36ded1, - 0xb5a4b052, 0x21f062d1, 0x72ab89b2, 0x74a45318, 0x8312e6bc, 0xb916965f, 0x8aa7c858, 0xfe7effad, + 0x6884ac63, 0x3ffecead, 0x2919b953, 0x0942fe50, 0x7a1d922e, 0xcdd6734a, 0x953a5bb6, 0x2c46922e, + 0xe2a5f143, 0xaa39103a, 0xa06afa5c, 0x135ffd59, 0xe8e82863, 0xf61ef029, 0xf75f042e, 0x2b363532, + 0x29b2df42, 0x16b1f64e, 0xd46e281b, 0x5280bf58, 0x60372229, 0x1be58e4f, 0xa8496f45, 0x1fb1a057, + 0x756b3844, 0x3bb79445, 0x0b375518, 0xcccb0102, 0xb682bf2e, 0x46431c02, 0x3a81073a, 0xa3771f1f, + 0x213a121f, 0x85dc2c1b, 0x56b4323b, 0xb34e8945, 0x3c40b33d, 0xfa276418, 0x1f818d29, 0xebe1e344, + 0xf6160a18, 0xf4fa384a, 0x34b09558, 0xb882b543, 0xe3ce2253, 0x6abf56d8, 0xe91b1155, 0x688ee6ad, + 0x2efc6058, 0x4792cd47, 0x0c32f757, 0x4c813a46, 0x8c93644a, 0x37507444, 0x813ad218, 0xdac06d4a, + 0xe4c63e4b, 0x21a1ea3c, 0x8d88556f, 0x30e9173a, 0x041f681b, 0xdc77ba50, 0xc0072753, 0xceddd44f, + 0x052d1743, 0xe3c77a4a, 0x13981c3a, 0x5685d918, 0x3c0e4e70, 0x3e56fb54, 0xb676ae0c, 0xac93c859, + 0x22279f43, 0x975a4542, 0xe527f071, 0xea162f2e, 0x3c65a32e, 0x5be5713b, 0x961ec418, 0xb202922e, + 0x5ef7be50, 0xce49f53e, 0x05803b47, 0x8463b055, 0x78576153, 0x3ec2ae3a, 0x4bbd7118, 0xafcee043, + 0x56a3e8ba, 0x6174de4d, 0x8d01ba4b, 0xc9af564e, 0xdbc9c547, 0xa627474d, 0xdada9244, 0xd3b3083a, + 0x523e071f, 0xd6b96f18, 0xbd527c46, 0xdf2bbb4d, 0xd37b4a4b, 0x3a6a2158, 0xc064b055, 0x18a8e055, + 0xec4dae3b, 0x0540416c, 0x475b4fbe, 0x064803b2, 0x48e9f062, 0x2898524b, 0xd315ff43, 0xf786d247, + 0xc7ea2f3e, 0xc087f043, 0xc163354b, 0x8250284d, 0xed300029, 0xbf36e05c, 0x8eb3ae4c, 0xe7aa623e, + 0x7ced0274, 0xdd362c1b, 0x362b995a, 0xca26b629, 0x3fc41618, 0xb97b364e, 0xa05b8729, 0x0f5e3c43, + 0xdf942618, 0x6aeb9b5b, 0xbf04762e, 0xfaaeb118, 0x87579958, 0x76520044, 0xc2660c5b, 0x628b201b, + 0xf193932e, 0x1c0ad045, 0xff908346, 0x8da9d4da, 0xed201c1f, 0xa47a2b1b, 0x330007d4, 0x8ba1ed47, + 0xb2f02d44, 0x7db62c1b, 0x781c454b, 0xc0300029, 0xb7062a45, 0x88b52e3a, 0x78dd6b63, 0x1cb9b718, + 0x5d358e47, 0x59912c3b, 0x79607544, 0x5197f759, 0xc023be48, 0xd1013743, 0x0f354057, 0x8e3aac3b, + 0x4114693e, 0x22316318, 0xe27dda50, 0x878eac3b, 0x4948a21f, 0x5db7f24c, 0x8ccb6157, 0x26a5de18, + 0x0a11bd43, 0x27bb1e41, 0x60a7a951, 0x3e16b35e, 0x07888b53, 0x5648a853, 0x0149fe50, 0xd070a34f, + 0x6454c96d, 0xd6e54758, 0xa96dc152, 0x65447861, 0xf6bdf95e, 0x10400202, 0x2c29d483, 0x18174732, + 0x1d840618, 0x12e61818, 0x089d3f3c, 0x917e931f, 0xd1b0c90e, 0x25bd3c42, 0xeb05775b, 0x7d550c59, + 0x6cfacb01, 0xe4224444, 0xa41dd943, 0x0f5aa643, 0x5e33731b, 0x81036d50, 0x6f46a0d1, 0x7731be43, + 0x14840e18, 0xf1e8d059, 0x661d2b1f, 0x40a3201b, 0x9407b843, 0xedf0254d, 0x7bd1a5bc, 0x073dbe51, + 0xe864a97b, 0x2efd947b, 0xb9ca0e45, 0x4e2113ad, 0xcc305731, 0xd39ca63c, 0x733df918, 0xda172b1f, + 0xaa03b34d, 0x7230fd4d, 0xf1ce6e3a, 0x2e9fab43, 0xa4010750, 0xa928bd18, 0x6809be42, 0xb19de348, + 0xff956270, 0x0d795f51, 0xd2dec247, 0x6df5774b, 0xbac11f79, 0xdfb05c75, 0x887683d8, 0xa1e83632, + 0x2c0f7671, 0x28bcb65d, 0xac2a7545, 0x3eebfc60, 0x304ad7c4, 0xa215a462, 0xc86f0f58, 0xcfb92ebe, + 0x5e23ed82, 0xf506184b, 0xec0f19b7, 0x060c59ad, 0x86ee3174, 0x85380774, 0xa199a562, 0x02b507ae, + 0x33eb2163, 0xf2112b1f, 0xb702ba50, 0x131b9618, 0x90ccd04a, 0x08f3273b, 0xecb61718, 0x64b8b44d, + 0x182bf4dc, 0xc7b68286, 0x6e318d5f, 0xfdb03654, 0xb3272e54, 0xe014ad4b, 0x274e4a31, 0x7806375c, + 0xbc34a748, 0x1b5ad94a, 0x6b54d10e, 0x73e2ae6e, 0x5529d483, 0x8455a76d, 0x99c13f47, 0x1d811741, + 0xa9782a78, 0x0b00464d, 0x7266ea50, 0x532dab46, 0x33e1413e, 0x780d0c18, 0x0fb0854e, 0x03370155, + 0x2693042e, 0xfa3d824a, 0x2bb1681b, 0x37ea2a18, 0x7fb8414b, 0x32e0713b, 0xacf38d3f, 0xa282716f, + 0xb1a09d7b, 0xa04b764b, 0x83c94d18, 0x05ee4c6d, 0x0e795f51, 0x46984352, 0xf80fc247, 0x3fccb946, + 0xd7ae244b, 0x0a8e0a4c, 0x57b141bc, 0x3647bed1, 0x1431b052, 0x803a8bbb, 0xfc69056b, 0xf5991862, + 0x14963b2e, 0xd35d5dda, 0xc6c73574, 0xc8f1405b, 0x0ca4224d, 0xecd36071, 0xa9461754, 0xe7a0ed72, + 0x559e8346, 0x1c9beec1, 0xc786ea4a, 0x9561b44d, 0x9788074d, 0x1a69934f, 0x23c5614c, 0x07c79d4b, + 0xc7ee52db, 0xc72df351, 0xcb135e44, 0xa0988346, 0xc211fc4c, 0x87dec34b, 0x1381074d, 0x04a65cb7, + 0x4409083a, 0x4a407a4c, 0x92b8d37d, 0xacf50b4d, 0xa58aa5bc, 0x448f801f, 0x9c83762e, 0x6fd5734a, + 0xfe2d454b, 0x84144c55, 0x05190e4c, 0xb2151448, 0x63867a3e, 0x16099018, 0x9c010d3c, 0x962d8f3d, + 0xd51ee453, 0x9d86801f, 0x68e87b47, 0x6bf7bb73, 0x5fc7910e, 0x10d90118, 0x3db04442, 0x729d3e4b, + 0xc397d842, 0x57bb15ad, 0x72f31f4e, 0xc9380043, 0x2bb24e18, 0xd9b8ab50, 0xb786801f, 0xf4dc4847, + 0x85f4bb51, 0x4435995b, 0x5ba07e40, 0x2c57392e, 0x3628124b, 0x9839b64b, 0x6fe8b24d, 0xaddce847, + 0x75260e45, 0x0c572a43, 0xfea21902, 0xb9f9742e, 0x5a70d443, 0x8fc5910e, 0x868d4744, 0x56245e02, + 0xd7eb5f02, 0x35c12c1b, 0x4373034b, 0x8786554c, 0xa6facf18, 0x4b11a31f, 0x3570664e, 0x5a64bc42, + 0x0b03983f, 0x8f457e4c, 0x0fd874c3, 0xb6cf31b2, 0x2bbc2d4e, 0x146ca5b2, 0x9d00b150, 0x048a4153, + 0xca4dcd43, 0xc1607cca, 0x8234cf57, 0x9c7daead, 0x3dc07658, 0xea5c6e4c, 0xf1a0084e, 0x16d2ee53, + 0x1b849418, 0xfe913a47, 0x1e988f62, 0x208b644c, 0xc55ee980, 0xbdbce747, 0xf59a384e, 0x0f56091b, + 0x7417b745, 0x0c37344e, 0x2c62ab47, 0xf8533a4d, 0x8030084d, 0x76b93c4b, 0xda6ea0ad, 0x3c54f618, + 0x63b0de1f, 0x7370d858, 0x1a70bb4c, 0xdda63b2e, 0x60b2ba50, 0x1ba7d048, 0xbe1b2c1b, 0xabea5747, + 0x29ad2e4d, 0xe8cd7642, 0x66c80e18, 0x138bf34a, 0xc6145e44, 0x2586794c, 0x07bc5478, 0x0da0b14d, + 0x8f95354e, 0x9eb11c62, 0xa1545e46, 0x2e7a2602, 0x408c9c3d, 0x59065d55, 0xf51d1a4c, 0x3bbc6a4e, + 0xc71b2a2e, 0xcdaaa545, 0x17d659d0, 0x5202e7ad, 0xf1b68445, 0x93375961, 0xbd88a043, 0x066ad655, + 0x890f6318, 0x7b7dca47, 0x99bdd662, 0x3bb4fc53, 0x1231efdc, 0xc0a99444, 0x96bbea47, 0x61ed8748, + 0x27dfa73b, 0x8d4d1754, 0x3460042e, 0x551f0c4c, 0x8d0e0718, 0x162ddc53, 0x53231718, 0x1ecd65d0, + 0x944d28bc, 0x3b79d058, 0xaff97fbc, 0x4860006c, 0xc101c90e, 0xace41743, 0xa5975d4c, 0x5cc2703e, + 0xb55a4450, 0x02d18840, 0xee2765ae, 0xd6012fd5, 0x24c94d7d, 0x8c6eec47, 0x7520ba5d, 0x9e15e460, + 0x8510b04c, 0x75ec3847, 0x1dfa6661, 0xe172b3ad, 0x5744c90e, 0x52a0a152, 0x8d6fad18, 0x67b74b6d, + 0x93a089b2, 0x0f3ac5d5, 0xe5de1855, 0x43d25747, 0x4bad804a, 0x55b408d8, 0x60a36441, 0xf553e860, + 0xdb2fa2c8, 0x03152b32, 0xdd27a7d5, 0x3116a8b8, 0x0a1d708c, 0xeee2f13c, 0x6acf436f, 0xce6eb4ca, + 0x101cd3d9, 0x1c48a6b8, 0xe57d6f44, 0x93dcf562, }; From 86fd7c5af6cf3f907c50cf25ff844cd23e271c70 Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Fri, 2 Sep 2011 11:01:45 -0400 Subject: [PATCH 29/29] Give hard-coded seed nodes a random last-seen time, to randomize order they're tried. --- src/net.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/net.cpp b/src/net.cpp index 1655cfbdc..952102ede 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1357,9 +1357,12 @@ void ThreadOpenConnections2(void* parg) { // It'll only connect to one or two seed nodes because once it connects, // it'll get a pile of addresses with newer timestamps. + // Seed nodes are given a random 'last seen time' of between one and two + // weeks ago. + const int64 nOneWeek = 7*24*60*60; CAddress addr; addr.ip = pnSeed[i]; - addr.nTime = 0; + addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek; AddAddress(addr); } fSeedUsed = true;