diff options
Diffstat (limited to 'src')
34 files changed, 254 insertions, 195 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index d91e959cff..c1912dafc5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -135,6 +135,7 @@ BITCOIN_CORE_H = \ script/sigcache.h \ script/sign.h \ script/standard.h \ + script/ismine.h \ streams.h \ support/allocators/secure.h \ support/allocators/zeroafterfree.h \ @@ -157,7 +158,6 @@ BITCOIN_CORE_H = \ wallet/db.h \ wallet/rpcwallet.h \ wallet/wallet.h \ - wallet/wallet_ismine.h \ wallet/walletdb.h \ zmq/zmqabstractnotifier.h \ zmq/zmqconfig.h\ @@ -199,10 +199,12 @@ libbitcoin_server_a_SOURCES = \ rpc/rawtransaction.cpp \ rpc/server.cpp \ script/sigcache.cpp \ + script/ismine.cpp \ timedata.cpp \ torcontrol.cpp \ txdb.cpp \ txmempool.cpp \ + ui_interface.cpp \ validationinterface.cpp \ versionbits.cpp \ $(BITCOIN_CORE_H) @@ -229,7 +231,6 @@ libbitcoin_wallet_a_SOURCES = \ wallet/rpcdump.cpp \ wallet/rpcwallet.cpp \ wallet/wallet.cpp \ - wallet/wallet_ismine.cpp \ wallet/walletdb.cpp \ policy/rbf.cpp \ $(BITCOIN_CORE_H) diff --git a/src/Makefile.test.include b/src/Makefile.test.include index f025b18c7e..08e2f6af4d 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -90,9 +90,11 @@ BITCOIN_TESTS =\ if ENABLE_WALLET BITCOIN_TESTS += \ - test/accounting_tests.cpp \ + wallet/test/wallet_test_fixture.cpp \ + wallet/test/wallet_test_fixture.h \ + wallet/test/accounting_tests.cpp \ wallet/test/wallet_tests.cpp \ - test/rpc_wallet_tests.cpp + wallet/test/rpc_wallet_tests.cpp endif test_test_bitcoin_SOURCES = $(BITCOIN_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES) diff --git a/src/crypto/ripemd160.h b/src/crypto/ripemd160.h index 687204fdae..bd41f02508 100644 --- a/src/crypto/ripemd160.h +++ b/src/crypto/ripemd160.h @@ -14,7 +14,7 @@ class CRIPEMD160 private: uint32_t s[5]; unsigned char buf[64]; - size_t bytes; + uint64_t bytes; public: static const size_t OUTPUT_SIZE = 20; diff --git a/src/crypto/sha1.h b/src/crypto/sha1.h index 7b2a21bc6c..8fb20810be 100644 --- a/src/crypto/sha1.h +++ b/src/crypto/sha1.h @@ -14,7 +14,7 @@ class CSHA1 private: uint32_t s[5]; unsigned char buf[64]; - size_t bytes; + uint64_t bytes; public: static const size_t OUTPUT_SIZE = 20; diff --git a/src/crypto/sha256.h b/src/crypto/sha256.h index 85cf33739a..5b15b6a233 100644 --- a/src/crypto/sha256.h +++ b/src/crypto/sha256.h @@ -14,7 +14,7 @@ class CSHA256 private: uint32_t s[8]; unsigned char buf[64]; - size_t bytes; + uint64_t bytes; public: static const size_t OUTPUT_SIZE = 32; diff --git a/src/crypto/sha512.h b/src/crypto/sha512.h index f1f17caf90..614681fae2 100644 --- a/src/crypto/sha512.h +++ b/src/crypto/sha512.h @@ -14,7 +14,7 @@ class CSHA512 private: uint64_t s[8]; unsigned char buf[128]; - size_t bytes; + uint64_t bytes; public: static const size_t OUTPUT_SIZE = 64; diff --git a/src/init.cpp b/src/init.cpp index 3667820a21..b06f448a00 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -94,7 +94,6 @@ enum BindFlags { }; static const char* FEE_ESTIMATES_FILENAME="fee_estimates.dat"; -CClientUIInterface uiInterface; // Declared but not defined in ui_interface.h ////////////////////////////////////////////////////////////////////////////// // @@ -266,18 +265,6 @@ void HandleSIGHUP(int) fReopenDebugLog = true; } -bool static InitError(const std::string &str) -{ - uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_ERROR); - return false; -} - -bool static InitWarning(const std::string &str) -{ - uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_WARNING); - return true; -} - bool static Bind(const CService &addr, unsigned int flags) { if (!(flags & BF_EXPLICIT) && IsLimited(addr)) return false; @@ -742,11 +729,6 @@ static std::string ResolveErrMsg(const char * const optname, const std::string& return strprintf(_("Cannot resolve -%s address: '%s'"), optname, strBind); } -static std::string AmountErrMsg(const char * const optname, const std::string& strValue) -{ - return strprintf(_("Invalid amount for -%s=<amount>: '%s'"), optname, strValue); -} - void InitLogging() { fPrintToConsole = GetBoolArg("-printtoconsole", false); @@ -1156,10 +1138,11 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (mapArgs.count("-externalip")) { BOOST_FOREACH(const std::string& strAddr, mapMultiArgs["-externalip"]) { - CService addrLocal(strAddr, GetListenPort(), fNameLookup); - if (!addrLocal.IsValid()) + CService addrLocal; + if (Lookup(strAddr.c_str(), addrLocal, GetListenPort(), fNameLookup) && addrLocal.IsValid()) + AddLocal(addrLocal, LOCAL_MANUAL); + else return InitError(ResolveErrMsg("externalip", strAddr)); - AddLocal(CService(strAddr, GetListenPort(), fNameLookup), LOCAL_MANUAL); } } diff --git a/src/keystore.cpp b/src/keystore.cpp index cc8a573367..d568a74350 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -19,6 +19,7 @@ bool CBasicKeyStore::GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) con { CKey key; if (!GetKey(address, key)) { + LOCK(cs_KeyStore); WatchKeyMap::const_iterator it = mapWatchKeys.find(address); if (it != mapWatchKeys.end()) { vchPubKeyOut = it->second; diff --git a/src/net.cpp b/src/net.cpp index f294e4c667..7dec8fc1cf 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1443,7 +1443,7 @@ void ThreadDNSAddressSeed() } else { vector<CNetAddr> vIPs; vector<CAddress> vAdd; - if (LookupHost(seed.host.c_str(), vIPs)) + if (LookupHost(seed.host.c_str(), vIPs, 0, true)) { BOOST_FOREACH(const CNetAddr& ip, vIPs) { @@ -1454,7 +1454,15 @@ void ThreadDNSAddressSeed() found++; } } - addrman.Add(vAdd, CNetAddr(seed.name, true)); + // TODO: The seed name resolve may fail, yielding an IP of [::], which results in + // addrman assigning the same source to results from different seeds. + // This should switch to a hard-coded stable dummy IP for each seed name, so that the + // resolve is not required at all. + if (!vIPs.empty()) { + CService seedSource; + Lookup(seed.name.c_str(), seedSource, 0, true); + addrman.Add(vAdd, seedSource); + } } } @@ -1884,7 +1892,7 @@ void static Discover(boost::thread_group& threadGroup) if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR) { vector<CNetAddr> vaddr; - if (LookupHost(pszHostName, vaddr)) + if (LookupHost(pszHostName, vaddr, 0, true)) { BOOST_FOREACH (const CNetAddr &addr, vaddr) { diff --git a/src/netbase.cpp b/src/netbase.cpp index 281c6bcb7f..b44a8b16e2 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -614,10 +614,12 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest proxyType nameProxy; GetNameProxy(nameProxy); - CService addrResolved(CNetAddr(strDest, fNameLookup && !HaveNameProxy()), port); - if (addrResolved.IsValid()) { - addr = addrResolved; - return ConnectSocket(addr, hSocketRet, nTimeout); + CService addrResolved; + if (Lookup(strDest.c_str(), addrResolved, port, fNameLookup && !HaveNameProxy())) { + if (addrResolved.IsValid()) { + addr = addrResolved; + return ConnectSocket(addr, hSocketRet, nTimeout); + } } addr = CService("0.0.0.0:0"); @@ -686,19 +688,19 @@ CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr, const uint32_t scope) scopeId = scope; } -CNetAddr::CNetAddr(const char *pszIp, bool fAllowLookup) +CNetAddr::CNetAddr(const char *pszIp) { Init(); std::vector<CNetAddr> vIP; - if (LookupHost(pszIp, vIP, 1, fAllowLookup)) + if (LookupHost(pszIp, vIP, 1, false)) *this = vIP[0]; } -CNetAddr::CNetAddr(const std::string &strIp, bool fAllowLookup) +CNetAddr::CNetAddr(const std::string &strIp) { Init(); std::vector<CNetAddr> vIP; - if (LookupHost(strIp.c_str(), vIP, 1, fAllowLookup)) + if (LookupHost(strIp.c_str(), vIP, 1, false)) *this = vIP[0]; } @@ -1121,35 +1123,35 @@ bool CService::SetSockAddr(const struct sockaddr *paddr) } } -CService::CService(const char *pszIpPort, bool fAllowLookup) +CService::CService(const char *pszIpPort) { Init(); CService ip; - if (Lookup(pszIpPort, ip, 0, fAllowLookup)) + if (Lookup(pszIpPort, ip, 0, false)) *this = ip; } -CService::CService(const char *pszIpPort, int portDefault, bool fAllowLookup) +CService::CService(const char *pszIpPort, int portDefault) { Init(); CService ip; - if (Lookup(pszIpPort, ip, portDefault, fAllowLookup)) + if (Lookup(pszIpPort, ip, portDefault, false)) *this = ip; } -CService::CService(const std::string &strIpPort, bool fAllowLookup) +CService::CService(const std::string &strIpPort) { Init(); CService ip; - if (Lookup(strIpPort.c_str(), ip, 0, fAllowLookup)) + if (Lookup(strIpPort.c_str(), ip, 0, false)) *this = ip; } -CService::CService(const std::string &strIpPort, int portDefault, bool fAllowLookup) +CService::CService(const std::string &strIpPort, int portDefault) { Init(); CService ip; - if (Lookup(strIpPort.c_str(), ip, portDefault, fAllowLookup)) + if (Lookup(strIpPort.c_str(), ip, portDefault, false)) *this = ip; } @@ -1243,7 +1245,7 @@ CSubNet::CSubNet(): memset(netmask, 0, sizeof(netmask)); } -CSubNet::CSubNet(const std::string &strSubnet, bool fAllowLookup) +CSubNet::CSubNet(const std::string &strSubnet) { size_t slash = strSubnet.find_last_of('/'); std::vector<CNetAddr> vIP; @@ -1253,7 +1255,7 @@ CSubNet::CSubNet(const std::string &strSubnet, bool fAllowLookup) memset(netmask, 255, sizeof(netmask)); std::string strAddress = strSubnet.substr(0, slash); - if (LookupHost(strAddress.c_str(), vIP, 1, fAllowLookup)) + if (LookupHost(strAddress.c_str(), vIP, 1, false)) { network = vIP[0]; if (slash != strSubnet.npos) diff --git a/src/netbase.h b/src/netbase.h index db736154fa..65187a17cf 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -49,8 +49,8 @@ class CNetAddr public: CNetAddr(); CNetAddr(const struct in_addr& ipv4Addr); - explicit CNetAddr(const char *pszIp, bool fAllowLookup = false); - explicit CNetAddr(const std::string &strIp, bool fAllowLookup = false); + explicit CNetAddr(const char *pszIp); + explicit CNetAddr(const std::string &strIp); void Init(); void SetIP(const CNetAddr& ip); @@ -119,7 +119,7 @@ class CSubNet public: CSubNet(); - explicit CSubNet(const std::string &strSubnet, bool fAllowLookup = false); + explicit CSubNet(const std::string &strSubnet); //constructor for single ip subnet (<ipv4>/32 or <ipv6>/128) explicit CSubNet(const CNetAddr &addr); @@ -154,10 +154,10 @@ class CService : public CNetAddr CService(const CNetAddr& ip, unsigned short port); CService(const struct in_addr& ipv4Addr, unsigned short port); CService(const struct sockaddr_in& addr); - explicit CService(const char *pszIpPort, int portDefault, bool fAllowLookup = false); - explicit CService(const char *pszIpPort, bool fAllowLookup = false); - explicit CService(const std::string& strIpPort, int portDefault, bool fAllowLookup = false); - explicit CService(const std::string& strIpPort, bool fAllowLookup = false); + explicit CService(const char *pszIpPort, int portDefault); + explicit CService(const char *pszIpPort); + explicit CService(const std::string& strIpPort, int portDefault); + explicit CService(const std::string& strIpPort); void Init(); void SetPort(unsigned short portIn); unsigned short GetPort() const; @@ -206,9 +206,9 @@ bool GetProxy(enum Network net, proxyType &proxyInfoOut); bool IsProxy(const CNetAddr &addr); bool SetNameProxy(const proxyType &addrProxy); bool HaveNameProxy(); -bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions = 0, bool fAllowLookup = true); -bool Lookup(const char *pszName, CService& addr, int portDefault = 0, bool fAllowLookup = true); -bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault = 0, bool fAllowLookup = true, unsigned int nMaxSolutions = 0); +bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup); +bool Lookup(const char *pszName, CService& addr, int portDefault, bool fAllowLookup); +bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions); bool LookupNumeric(const char *pszName, CService& addr, int portDefault = 0); bool ConnectSocket(const CService &addr, SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed = 0); bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault, int nTimeout, bool *outProxyConnectionFailed = 0); diff --git a/src/prevector.h b/src/prevector.h index 1da459bcfe..a0e1e140b4 100644 --- a/src/prevector.h +++ b/src/prevector.h @@ -298,9 +298,8 @@ public: } void resize(size_type new_size) { - while (size() > new_size) { - item_ptr(size() - 1)->~T(); - _size--; + if (size() > new_size) { + erase(item_ptr(new_size), end()); } if (new_size > capacity()) { change_capacity(new_size); @@ -368,10 +367,7 @@ public: } iterator erase(iterator pos) { - (*pos).~T(); - memmove(&(*pos), &(*pos) + 1, ((char*)&(*end())) - ((char*)(1 + &(*pos)))); - _size--; - return pos; + return erase(pos, pos + 1); } iterator erase(iterator first, iterator last) { @@ -396,7 +392,7 @@ public: } void pop_back() { - _size--; + erase(end() - 1, end()); } T& front() { @@ -416,12 +412,7 @@ public: } void swap(prevector<N, T, Size, Diff>& other) { - if (_size & other._size & 1) { - std::swap(_union.capacity, other._union.capacity); - std::swap(_union.indirect, other._union.indirect); - } else { - std::swap(_union, other._union); - } + std::swap(_union, other._union); std::swap(_size, other._size); } diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 2670a85c4f..6960415e2e 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -467,6 +467,7 @@ static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats) CCoins coins; if (pcursor->GetKey(key) && pcursor->GetValue(coins)) { stats.nTransactions++; + ss << key; for (unsigned int i=0; i<coins.vout.size(); i++) { const CTxOut &out = coins.vout[i]; if (!out.IsNull()) { @@ -814,17 +815,30 @@ UniValue getchaintips(const UniValue& params, bool fHelp) LOCK(cs_main); - /* Build up a list of chain tips. We start with the list of all - known blocks, and successively remove blocks that appear as pprev - of another block. */ + /* + * Idea: the set of chain tips is chainActive.tip, plus orphan blocks which do not have another orphan building off of them. + * Algorithm: + * - Make one pass through mapBlockIndex, picking out the orphan blocks, and also storing a set of the orphan block's pprev pointers. + * - Iterate through the orphan blocks. If the block isn't pointed to by another orphan, it is a chain tip. + * - add chainActive.Tip() + */ std::set<const CBlockIndex*, CompareBlocksByHeight> setTips; - BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex) - setTips.insert(item.second); + std::set<const CBlockIndex*> setOrphans; + std::set<const CBlockIndex*> setPrevs; + BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex) { - const CBlockIndex* pprev = item.second->pprev; - if (pprev) - setTips.erase(pprev); + if (!chainActive.Contains(item.second)) { + setOrphans.insert(item.second); + setPrevs.insert(item.second->pprev); + } + } + + for (std::set<const CBlockIndex*>::iterator it = setOrphans.begin(); it != setOrphans.end(); ++it) + { + if (setPrevs.erase(*it) == 0) { + setTips.insert(*it); + } } // Always report the currently active tip. diff --git a/src/wallet/wallet_ismine.cpp b/src/script/ismine.cpp index ebda5cc53d..535c56b57a 100644 --- a/src/wallet/wallet_ismine.cpp +++ b/src/script/ismine.cpp @@ -3,7 +3,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "wallet_ismine.h" +#include "ismine.h" #include "key.h" #include "keystore.h" diff --git a/src/wallet/wallet_ismine.h b/src/script/ismine.h index 51afd1b140..4b7db8802b 100644 --- a/src/wallet/wallet_ismine.h +++ b/src/script/ismine.h @@ -3,8 +3,8 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef BITCOIN_WALLET_WALLET_ISMINE_H -#define BITCOIN_WALLET_WALLET_ISMINE_H +#ifndef BITCOIN_SCRIPT_ISMINE_H +#define BITCOIN_SCRIPT_ISMINE_H #include "script/standard.h" @@ -31,4 +31,4 @@ typedef uint8_t isminefilter; isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey); isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest); -#endif // BITCOIN_WALLET_WALLET_ISMINE_H +#endif // BITCOIN_SCRIPT_ISMINE_H diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp index edf1650ca5..d48a68ba54 100644 --- a/src/test/multisig_tests.cpp +++ b/src/test/multisig_tests.cpp @@ -9,12 +9,10 @@ #include "script/script_error.h" #include "script/interpreter.h" #include "script/sign.h" +#include "script/ismine.h" #include "uint256.h" #include "test/test_bitcoin.h" -#ifdef ENABLE_WALLET -#include "wallet/wallet_ismine.h" -#endif #include <boost/foreach.hpp> #include <boost/test/unit_test.hpp> @@ -210,10 +208,8 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1) CTxDestination addr; BOOST_CHECK(ExtractDestination(s, addr)); BOOST_CHECK(addr == keyaddr[0]); -#ifdef ENABLE_WALLET BOOST_CHECK(IsMine(keystore, s)); BOOST_CHECK(!IsMine(emptykeystore, s)); -#endif } { vector<valtype> solutions; @@ -225,10 +221,8 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1) CTxDestination addr; BOOST_CHECK(ExtractDestination(s, addr)); BOOST_CHECK(addr == keyaddr[0]); -#ifdef ENABLE_WALLET BOOST_CHECK(IsMine(keystore, s)); BOOST_CHECK(!IsMine(emptykeystore, s)); -#endif } { vector<valtype> solutions; @@ -239,11 +233,9 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1) BOOST_CHECK_EQUAL(solutions.size(), 4U); CTxDestination addr; BOOST_CHECK(!ExtractDestination(s, addr)); -#ifdef ENABLE_WALLET BOOST_CHECK(IsMine(keystore, s)); BOOST_CHECK(!IsMine(emptykeystore, s)); BOOST_CHECK(!IsMine(partialkeystore, s)); -#endif } { vector<valtype> solutions; @@ -258,11 +250,9 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1) BOOST_CHECK(addrs[0] == keyaddr[0]); BOOST_CHECK(addrs[1] == keyaddr[1]); BOOST_CHECK(nRequired == 1); -#ifdef ENABLE_WALLET BOOST_CHECK(IsMine(keystore, s)); BOOST_CHECK(!IsMine(emptykeystore, s)); BOOST_CHECK(!IsMine(partialkeystore, s)); -#endif } { vector<valtype> solutions; diff --git a/src/test/prevector_tests.cpp b/src/test/prevector_tests.cpp index 01a45b540d..b39b903530 100644 --- a/src/test/prevector_tests.cpp +++ b/src/test/prevector_tests.cpp @@ -19,9 +19,11 @@ template<unsigned int N, typename T> class prevector_tester { typedef std::vector<T> realtype; realtype real_vector; + realtype real_vector_alt; typedef prevector<N, T> pretype; pretype pre_vector; + pretype pre_vector_alt; typedef typename pretype::size_type Size; @@ -149,6 +151,12 @@ public: pre_vector.shrink_to_fit(); test(); } + + void swap() { + real_vector.swap(real_vector_alt); + pre_vector.swap(pre_vector_alt); + test(); + } }; BOOST_AUTO_TEST_CASE(PrevectorTestInt) @@ -204,12 +212,15 @@ BOOST_AUTO_TEST_CASE(PrevectorTestInt) if (test.size() > 0) { test.update(insecure_rand() % test.size(), insecure_rand()); } - if (((r >> 11) & 1024) == 11) { + if (((r >> 11) % 1024) == 11) { test.clear(); } - if (((r >> 21) & 512) == 12) { + if (((r >> 21) % 512) == 12) { test.assign(insecure_rand() % 32, insecure_rand()); } + if (((r >> 15) % 64) == 3) { + test.swap(); + } } } } diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index 28b85e8d29..d10284fe94 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -9,12 +9,9 @@ #include "script/script.h" #include "script/script_error.h" #include "script/sign.h" +#include "script/ismine.h" #include "test/test_bitcoin.h" -#ifdef ENABLE_WALLET -#include "wallet/wallet_ismine.h" -#endif - #include <vector> #include <boost/test/unit_test.hpp> @@ -101,9 +98,7 @@ BOOST_AUTO_TEST_CASE(sign) txTo[i].vin[0].prevout.n = i; txTo[i].vin[0].prevout.hash = txFrom.GetHash(); txTo[i].vout[0].nValue = 1; -#ifdef ENABLE_WALLET BOOST_CHECK_MESSAGE(IsMine(keystore, txFrom.vout[i].scriptPubKey), strprintf("IsMine %d", i)); -#endif } for (int i = 0; i < 8; i++) { @@ -198,9 +193,7 @@ BOOST_AUTO_TEST_CASE(set) txTo[i].vin[0].prevout.hash = txFrom.GetHash(); txTo[i].vout[0].nValue = 1*CENT; txTo[i].vout[0].scriptPubKey = inner[i]; -#ifdef ENABLE_WALLET BOOST_CHECK_MESSAGE(IsMine(keystore, txFrom.vout[i].scriptPubKey), strprintf("IsMine %d", i)); -#endif } for (int i = 0; i < 4; i++) { diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 97b9996252..9bcb07626a 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -19,10 +19,6 @@ #include "ui_interface.h" #include "rpc/server.h" #include "rpc/register.h" -#ifdef ENABLE_WALLET -#include "wallet/db.h" -#include "wallet/wallet.h" -#endif #include "test/testutil.h" @@ -30,8 +26,6 @@ #include <boost/test/unit_test.hpp> #include <boost/thread.hpp> -CClientUIInterface uiInterface; // Declared but not defined in ui_interface.h - extern bool fPrintToConsole; extern void noui_connect(); @@ -57,10 +51,6 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha // Ideally we'd move all the RPC tests to the functional testing framework // instead of unit tests, but for now we need these here. RegisterAllCoreRPCCommands(tableRPC); -#ifdef ENABLE_WALLET - bitdb.MakeMock(); - RegisterWalletRPCCommands(tableRPC); -#endif ClearDatadirCache(); pathTemp = GetTempPath() / strprintf("test_bitcoin_%lu_%i", (unsigned long)GetTime(), (int)(GetRand(100000))); boost::filesystem::create_directories(pathTemp); @@ -69,12 +59,6 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha pcoinsdbview = new CCoinsViewDB(1 << 23, true); pcoinsTip = new CCoinsViewCache(pcoinsdbview); InitBlockIndex(chainparams); -#ifdef ENABLE_WALLET - bool fFirstRun; - pwalletMain = new CWallet("wallet.dat"); - pwalletMain->LoadWallet(fFirstRun); - RegisterValidationInterface(pwalletMain); -#endif nScriptCheckThreads = 3; for (int i=0; i < nScriptCheckThreads-1; i++) threadGroup.create_thread(&ThreadScriptCheck); @@ -86,19 +70,10 @@ TestingSetup::~TestingSetup() UnregisterNodeSignals(GetNodeSignals()); threadGroup.interrupt_all(); threadGroup.join_all(); -#ifdef ENABLE_WALLET - UnregisterValidationInterface(pwalletMain); - delete pwalletMain; - pwalletMain = NULL; -#endif UnloadBlockIndex(); delete pcoinsTip; delete pcoinsdbview; delete pblocktree; -#ifdef ENABLE_WALLET - bitdb.Flush(true); - bitdb.Reset(); -#endif boost::filesystem::remove_all(pathTemp); } diff --git a/src/test/test_bitcoin.h b/src/test/test_bitcoin.h index 769ae5a132..57f66f6c6d 100644 --- a/src/test/test_bitcoin.h +++ b/src/test/test_bitcoin.h @@ -25,8 +25,7 @@ struct BasicTestingSetup { }; /** Testing setup that configures a complete environment. - * Included are data directory, coins database, script check threads - * and wallet (if enabled) setup. + * Included are data directory, coins database, script check threads setup. */ struct TestingSetup: public BasicTestingSetup { CCoinsViewDB *pcoinsdbview; diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 1c7bc2dbee..47d834c7b4 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -438,7 +438,7 @@ void TorController::add_onion_cb(TorControlConnection& conn, const TorControlRep private_key = i->second; } - service = CService(service_id+".onion", GetListenPort(), false); + service = CService(service_id+".onion", GetListenPort()); LogPrintf("tor: Got service ID %s, advertising service %s\n", service_id, service.ToString()); if (WriteBinaryFile(GetPrivateKeyFile(), private_key)) { LogPrint("tor", "tor: Cached service private key to %s\n", GetPrivateKeyFile()); diff --git a/src/txdb.cpp b/src/txdb.cpp index be86cceeb3..19ca178654 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -134,12 +134,8 @@ bool CCoinsViewDBCursor::Valid() const void CCoinsViewDBCursor::Next() { pcursor->Next(); - if (pcursor->Valid()) { - bool ok = pcursor->GetKey(keyTmp); - assert(ok); // If GetKey fails here something must be wrong with underlying database, we cannot handle that here - } else { + if (!pcursor->Valid() || !pcursor->GetKey(keyTmp)) keyTmp.first = 0; // Invalidate cached key after last record so that Valid() and GetKey() return false - } } bool CBlockTreeDB::WriteBatchSync(const std::vector<std::pair<int, const CBlockFileInfo*> >& fileInfo, int nLastFile, const std::vector<const CBlockIndex*>& blockinfo) { diff --git a/src/ui_interface.cpp b/src/ui_interface.cpp new file mode 100644 index 0000000000..c778e40a90 --- /dev/null +++ b/src/ui_interface.cpp @@ -0,0 +1,24 @@ +// Copyright (c) 2010-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "ui_interface.h" +#include "util.h" + +CClientUIInterface uiInterface; + +bool InitError(const std::string& str) +{ + uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_ERROR); + return false; +} + +void InitWarning(const std::string& str) +{ + uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_WARNING); +} + +std::string AmountErrMsg(const char* const optname, const std::string& strValue) +{ + return strprintf(_("Invalid amount for -%s=<amount>: '%s'"), optname, strValue); +} diff --git a/src/ui_interface.h b/src/ui_interface.h index 0b51d52e65..a27918c507 100644 --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -100,6 +100,14 @@ public: boost::signals2::signal<void (void)> BannedListChanged; }; +/** Show warning message **/ +void InitWarning(const std::string& str); + +/** Show error message **/ +bool InitError(const std::string& str); + +std::string AmountErrMsg(const char* const optname, const std::string& strValue); + extern CClientUIInterface uiInterface; #endif // BITCOIN_UI_INTERFACE_H diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 3078cebd48..d1e201ec11 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2443,7 +2443,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) "Note that inputs which were signed may need to be resigned after completion since in/outputs have been added.\n" "The inputs added will not be signed, use signrawtransaction for that.\n" "Note that all existing inputs must have their previous output transaction be in the wallet.\n" - "Note that all inputs selected must be of standard form and P2SH scripts must be" + "Note that all inputs selected must be of standard form and P2SH scripts must be\n" "in the wallet using importaddress or addmultisigaddress (to calculate fees).\n" "Only pay-to-pubkey, multisig, and P2SH versions thereof are currently supported for watch-only\n" "\nArguments:\n" @@ -2455,7 +2455,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) " \"includeWatching\" (boolean, optional, default false) Also select inputs which are watch only\n" " \"lockUnspents\" (boolean, optional, default false) Lock selected unspent outputs\n" " }\n" - " for backward compatibility: passing in a true instzead of an object will result in {\"includeWatching\":true}\n" + " for backward compatibility: passing in a true instead of an object will result in {\"includeWatching\":true}\n" "\nResult:\n" "{\n" " \"hex\": \"value\", (string) The resulting raw transaction (hex-encoded string)\n" diff --git a/src/test/accounting_tests.cpp b/src/wallet/test/accounting_tests.cpp index dad191c684..d075b2b641 100644 --- a/src/test/accounting_tests.cpp +++ b/src/wallet/test/accounting_tests.cpp @@ -5,7 +5,7 @@ #include "wallet/wallet.h" #include "wallet/walletdb.h" -#include "test/test_bitcoin.h" +#include "wallet/test/wallet_test_fixture.h" #include <stdint.h> @@ -14,7 +14,7 @@ extern CWallet* pwalletMain; -BOOST_FIXTURE_TEST_SUITE(accounting_tests, TestingSetup) +BOOST_FIXTURE_TEST_SUITE(accounting_tests, WalletTestingSetup) static void GetResults(CWalletDB& walletdb, std::map<CAmount, CAccountingEntry>& results) diff --git a/src/test/rpc_wallet_tests.cpp b/src/wallet/test/rpc_wallet_tests.cpp index 3443be2093..4e7d177f51 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/wallet/test/rpc_wallet_tests.cpp @@ -9,7 +9,7 @@ #include "main.h" #include "wallet/wallet.h" -#include "test/test_bitcoin.h" +#include "wallet/test/wallet_test_fixture.h" #include <boost/algorithm/string.hpp> #include <boost/test/unit_test.hpp> @@ -23,7 +23,7 @@ extern UniValue CallRPC(string args); extern CWallet* pwalletMain; -BOOST_FIXTURE_TEST_SUITE(rpc_wallet_tests, TestingSetup) +BOOST_FIXTURE_TEST_SUITE(rpc_wallet_tests, WalletTestingSetup) BOOST_AUTO_TEST_CASE(rpc_addmultisig) { diff --git a/src/wallet/test/wallet_test_fixture.cpp b/src/wallet/test/wallet_test_fixture.cpp new file mode 100644 index 0000000000..9036ee26d8 --- /dev/null +++ b/src/wallet/test/wallet_test_fixture.cpp @@ -0,0 +1,28 @@ +#include "wallet/test/wallet_test_fixture.h" + +#include "rpc/server.h" +#include "wallet/db.h" +#include "wallet/wallet.h" + +WalletTestingSetup::WalletTestingSetup(const std::string& chainName): + TestingSetup(chainName) +{ + bitdb.MakeMock(); + + bool fFirstRun; + pwalletMain = new CWallet("wallet_test.dat"); + pwalletMain->LoadWallet(fFirstRun); + RegisterValidationInterface(pwalletMain); + + RegisterWalletRPCCommands(tableRPC); +} + +WalletTestingSetup::~WalletTestingSetup() +{ + UnregisterValidationInterface(pwalletMain); + delete pwalletMain; + pwalletMain = NULL; + + bitdb.Flush(true); + bitdb.Reset(); +} diff --git a/src/wallet/test/wallet_test_fixture.h b/src/wallet/test/wallet_test_fixture.h new file mode 100644 index 0000000000..97a6d98397 --- /dev/null +++ b/src/wallet/test/wallet_test_fixture.h @@ -0,0 +1,18 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_WALLET_TEST_FIXTURE_H +#define BITCOIN_WALLET_TEST_FIXTURE_H + +#include "test/test_bitcoin.h" + +/** Testing setup and teardown for wallet. + */ +struct WalletTestingSetup: public TestingSetup { + WalletTestingSetup(const std::string& chainName = CBaseChainParams::MAIN); + ~WalletTestingSetup(); +}; + +#endif + diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index e84d588026..b759a6b2e8 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -9,7 +9,7 @@ #include <utility> #include <vector> -#include "test/test_bitcoin.h" +#include "wallet/test/wallet_test_fixture.h" #include <boost/foreach.hpp> #include <boost/test/unit_test.hpp> @@ -25,7 +25,7 @@ using namespace std; typedef set<pair<const CWalletTx*,unsigned int> > CoinSet; -BOOST_FIXTURE_TEST_SUITE(wallet_tests, TestingSetup) +BOOST_FIXTURE_TEST_SUITE(wallet_tests, WalletTestingSetup) static CWallet wallet; static vector<COutput> vCoins; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 8161c659ab..955a0a3d60 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -23,6 +23,7 @@ #include "timedata.h" #include "txmempool.h" #include "util.h" +#include "ui_interface.h" #include "utilmoneystr.h" #include <assert.h> @@ -365,22 +366,6 @@ void CWallet::Flush(bool shutdown) bitdb.Flush(shutdown); } -bool static UIError(const std::string &str) -{ - uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_ERROR); - return false; -} - -void static UIWarning(const std::string &str) -{ - uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_WARNING); -} - -static std::string AmountErrMsg(const char * const optname, const std::string& strValue) -{ - return strprintf(_("Invalid amount for -%s=<amount>: '%s'"), optname, strValue); -} - bool CWallet::Verify() { std::string walletFile = GetArg("-wallet", DEFAULT_WALLET_DAT); @@ -390,7 +375,7 @@ bool CWallet::Verify() // Wallet file must be a plain filename without a directory if (walletFile != boost::filesystem::basename(walletFile) + boost::filesystem::extension(walletFile)) - return UIError(strprintf(_("Wallet %s resides outside data directory %s"), walletFile, GetDataDir().string())); + return InitError(strprintf(_("Wallet %s resides outside data directory %s"), walletFile, GetDataDir().string())); if (!bitdb.Open(GetDataDir())) { @@ -407,7 +392,7 @@ bool CWallet::Verify() // try again if (!bitdb.Open(GetDataDir())) { // if it still fails, it probably means we can't even create the database env - return UIError(strprintf(_("Error initializing wallet database environment %s!"), GetDataDir())); + return InitError(strprintf(_("Error initializing wallet database environment %s!"), GetDataDir())); } } @@ -423,14 +408,14 @@ bool CWallet::Verify() CDBEnv::VerifyResult r = bitdb.Verify(walletFile, CWalletDB::Recover); if (r == CDBEnv::RECOVER_OK) { - UIWarning(strprintf(_("Warning: Wallet file corrupt, data salvaged!" + InitWarning(strprintf(_("Warning: Wallet file corrupt, data salvaged!" " Original %s saved as %s in %s; if" " your balance or transactions are incorrect you should" " restore from a backup."), walletFile, "wallet.{timestamp}.bak", GetDataDir())); } if (r == CDBEnv::RECOVER_FAIL) - return UIError(strprintf(_("%s corrupt, salvage failed"), walletFile)); + return InitError(strprintf(_("%s corrupt, salvage failed"), walletFile)); } return true; @@ -3075,7 +3060,7 @@ bool CWallet::InitLoadWallet() CWallet *tempWallet = new CWallet(walletFile); DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx); if (nZapWalletRet != DB_LOAD_OK) { - return UIError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); + return InitError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); } delete tempWallet; @@ -3091,22 +3076,22 @@ bool CWallet::InitLoadWallet() if (nLoadWalletRet != DB_LOAD_OK) { if (nLoadWalletRet == DB_CORRUPT) - return UIError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); + return InitError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); else if (nLoadWalletRet == DB_NONCRITICAL_ERROR) { - UIWarning(strprintf(_("Error reading %s! All keys read correctly, but transaction data" + InitWarning(strprintf(_("Error reading %s! All keys read correctly, but transaction data" " or address book entries might be missing or incorrect."), walletFile)); } else if (nLoadWalletRet == DB_TOO_NEW) - return UIError(strprintf(_("Error loading %s: Wallet requires newer version of %s"), + return InitError(strprintf(_("Error loading %s: Wallet requires newer version of %s"), walletFile, _(PACKAGE_NAME))); else if (nLoadWalletRet == DB_NEED_REWRITE) { - return UIError(strprintf(_("Wallet needed to be rewritten: restart %s to complete"), _(PACKAGE_NAME))); + return InitError(strprintf(_("Wallet needed to be rewritten: restart %s to complete"), _(PACKAGE_NAME))); } else - return UIError(strprintf(_("Error loading %s"), walletFile)); + return InitError(strprintf(_("Error loading %s"), walletFile)); } if (GetBoolArg("-upgradewallet", fFirstRun)) @@ -3122,7 +3107,7 @@ bool CWallet::InitLoadWallet() LogPrintf("Allowing wallet upgrade up to %i\n", nMaxVersion); if (nMaxVersion < walletInstance->GetVersion()) { - return UIError(_("Cannot downgrade wallet")); + return InitError(_("Cannot downgrade wallet")); } walletInstance->SetMaxVersion(nMaxVersion); } @@ -3136,7 +3121,7 @@ bool CWallet::InitLoadWallet() if (walletInstance->GetKeyFromPool(newDefaultKey)) { walletInstance->SetDefaultKey(newDefaultKey); if (!walletInstance->SetAddressBook(walletInstance->vchDefaultKey.GetID(), "", "receive")) - return UIError(_("Cannot write default address") += "\n"); + return InitError(_("Cannot write default address") += "\n"); } walletInstance->SetBestChain(chainActive.GetLocator()); @@ -3170,7 +3155,7 @@ bool CWallet::InitLoadWallet() block = block->pprev; if (pindexRescan != block) - return UIError(_("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)")); + return InitError(_("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)")); } uiInterface.InitMessage(_("Rescanning...")); @@ -3220,28 +3205,28 @@ bool CWallet::ParameterInteraction() if (ParseMoney(mapArgs["-mintxfee"], n) && n > 0) CWallet::minTxFee = CFeeRate(n); else - return UIError(AmountErrMsg("mintxfee", mapArgs["-mintxfee"])); + return InitError(AmountErrMsg("mintxfee", mapArgs["-mintxfee"])); } if (mapArgs.count("-fallbackfee")) { CAmount nFeePerK = 0; if (!ParseMoney(mapArgs["-fallbackfee"], nFeePerK)) - return UIError(strprintf(_("Invalid amount for -fallbackfee=<amount>: '%s'"), mapArgs["-fallbackfee"])); + return InitError(strprintf(_("Invalid amount for -fallbackfee=<amount>: '%s'"), mapArgs["-fallbackfee"])); if (nFeePerK > HIGH_TX_FEE_PER_KB) - UIWarning(_("-fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available.")); + InitWarning(_("-fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available.")); CWallet::fallbackFee = CFeeRate(nFeePerK); } if (mapArgs.count("-paytxfee")) { CAmount nFeePerK = 0; if (!ParseMoney(mapArgs["-paytxfee"], nFeePerK)) - return UIError(AmountErrMsg("paytxfee", mapArgs["-paytxfee"])); + return InitError(AmountErrMsg("paytxfee", mapArgs["-paytxfee"])); if (nFeePerK > HIGH_TX_FEE_PER_KB) - UIWarning(_("-paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.")); + InitWarning(_("-paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.")); payTxFee = CFeeRate(nFeePerK, 1000); if (payTxFee < ::minRelayTxFee) { - return UIError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"), + return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"), mapArgs["-paytxfee"], ::minRelayTxFee.ToString())); } } @@ -3249,13 +3234,13 @@ bool CWallet::ParameterInteraction() { CAmount nMaxFee = 0; if (!ParseMoney(mapArgs["-maxtxfee"], nMaxFee)) - return UIError(AmountErrMsg("maxtxfee", mapArgs["-maxtxfee"])); + return InitError(AmountErrMsg("maxtxfee", mapArgs["-maxtxfee"])); if (nMaxFee > HIGH_MAX_TX_FEE) - UIWarning(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction.")); + InitWarning(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction.")); maxTxFee = nMaxFee; if (CFeeRate(maxTxFee, 1000) < ::minRelayTxFee) { - return UIError(strprintf(_("Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"), + return InitError(strprintf(_("Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"), mapArgs["-maxtxfee"], ::minRelayTxFee.ToString())); } } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index aab4b217ca..fa8740eb7f 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -12,8 +12,8 @@ #include "ui_interface.h" #include "utilstrencodings.h" #include "validationinterface.h" +#include "script/ismine.h" #include "wallet/crypter.h" -#include "wallet/wallet_ismine.h" #include "wallet/walletdb.h" #include "wallet/rpcwallet.h" diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp index f5839620ff..b6c907980f 100644 --- a/src/zmq/zmqpublishnotifier.cpp +++ b/src/zmq/zmqpublishnotifier.cpp @@ -9,6 +9,11 @@ static std::multimap<std::string, CZMQAbstractPublishNotifier*> mapPublishNotifiers; +static const char *MSG_HASHBLOCK = "hashblock"; +static const char *MSG_HASHTX = "hashtx"; +static const char *MSG_RAWBLOCK = "rawblock"; +static const char *MSG_RAWTX = "rawtx"; + // Internal function to send multipart message static int zmq_send_multipart(void *sock, const void* data, size_t size, ...) { @@ -118,6 +123,23 @@ void CZMQAbstractPublishNotifier::Shutdown() psocket = 0; } +bool CZMQAbstractPublishNotifier::SendMessage(const char *command, const void* data, size_t size) +{ + assert(psocket); + + /* send three parts, command & data & a LE 4byte sequence number */ + unsigned char msgseq[sizeof(uint32_t)]; + WriteLE32(&msgseq[0], nSequence); + int rc = zmq_send_multipart(psocket, command, strlen(command), data, size, msgseq, (size_t)sizeof(uint32_t), (void*)0); + if (rc == -1) + return false; + + /* increment memory only sequence number after sending */ + nSequence++; + + return true; +} + bool CZMQPublishHashBlockNotifier::NotifyBlock(const CBlockIndex *pindex) { uint256 hash = pindex->GetBlockHash(); @@ -125,8 +147,7 @@ bool CZMQPublishHashBlockNotifier::NotifyBlock(const CBlockIndex *pindex) char data[32]; for (unsigned int i = 0; i < 32; i++) data[31 - i] = hash.begin()[i]; - int rc = zmq_send_multipart(psocket, "hashblock", 9, data, 32, 0); - return rc == 0; + return SendMessage(MSG_HASHBLOCK, data, 32); } bool CZMQPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &transaction) @@ -136,8 +157,7 @@ bool CZMQPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &t char data[32]; for (unsigned int i = 0; i < 32; i++) data[31 - i] = hash.begin()[i]; - int rc = zmq_send_multipart(psocket, "hashtx", 6, data, 32, 0); - return rc == 0; + return SendMessage(MSG_HASHTX, data, 32); } bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex) @@ -158,8 +178,7 @@ bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex) ss << block; } - int rc = zmq_send_multipart(psocket, "rawblock", 8, &(*ss.begin()), ss.size(), 0); - return rc == 0; + return SendMessage(MSG_RAWBLOCK, &(*ss.begin()), ss.size()); } bool CZMQPublishRawTransactionNotifier::NotifyTransaction(const CTransaction &transaction) @@ -168,6 +187,5 @@ bool CZMQPublishRawTransactionNotifier::NotifyTransaction(const CTransaction &tr LogPrint("zmq", "zmq: Publish rawtx %s\n", hash.GetHex()); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss << transaction; - int rc = zmq_send_multipart(psocket, "rawtx", 5, &(*ss.begin()), ss.size(), 0); - return rc == 0; + return SendMessage(MSG_RAWTX, &(*ss.begin()), ss.size()); } diff --git a/src/zmq/zmqpublishnotifier.h b/src/zmq/zmqpublishnotifier.h index 44d5cbea67..22f02a3d0d 100644 --- a/src/zmq/zmqpublishnotifier.h +++ b/src/zmq/zmqpublishnotifier.h @@ -11,7 +11,19 @@ class CBlockIndex; class CZMQAbstractPublishNotifier : public CZMQAbstractNotifier { +private: + uint32_t nSequence; //! upcounting per message sequence number + public: + + /* send zmq multipart message + parts: + * command + * data + * message sequence number + */ + bool SendMessage(const char *command, const void* data, size_t size); + bool Initialize(void *pcontext); void Shutdown(); }; |