diff options
Diffstat (limited to 'src')
102 files changed, 860 insertions, 362 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index b82c6dc37a..cc8dded413 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -94,6 +94,7 @@ BITCOIN_CORE_H = \ consensus/params.h \ consensus/validation.h \ core_io.h \ + core_memusage.h \ eccryptoverify.h \ ecwrapper.h \ hash.h \ diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 6b7c42285d..2ec3468e06 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -322,7 +322,7 @@ RES_MOVIES = $(wildcard qt/res/movies/spinner-*.png) BITCOIN_RC = qt/res/bitcoin-qt-res.rc BITCOIN_QT_INCLUDES = -I$(builddir)/qt -I$(srcdir)/qt -I$(srcdir)/qt/forms \ - -I$(builddir)/qt/forms + -I$(builddir)/qt/forms -DQT_NO_KEYWORDS qt_libbitcoinqt_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \ $(QT_INCLUDES) $(QT_DBUS_INCLUDES) $(PROTOBUF_CFLAGS) $(QR_CFLAGS) diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index d451720141..1c5a312874 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -97,12 +97,6 @@ static bool AppInitRPC(int argc, char* argv[]) UniValue CallRPC(const string& strMethod, const UniValue& params) { - if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "") - throw runtime_error(strprintf( - _("You must set rpcpassword=<password> in the configuration file:\n%s\n" - "If the file does not exist, create it with owner-readable-only file permissions."), - GetConfigFile().string().c_str())); - // Connect to localhost bool fUseSSL = GetBoolArg("-rpcssl", false); boost::asio::io_service io_service; @@ -116,10 +110,24 @@ UniValue CallRPC(const string& strMethod, const UniValue& params) if (!fConnected) throw CConnectionFailed("couldn't connect to server"); + // Find credentials to use + std::string strRPCUserColonPass; + if (mapArgs["-rpcpassword"] == "") { + // Try fall back to cookie-based authentication if no password is provided + if (!GetAuthCookie(&strRPCUserColonPass)) { + throw runtime_error(strprintf( + _("You must set rpcpassword=<password> in the configuration file:\n%s\n" + "If the file does not exist, create it with owner-readable-only file permissions."), + GetConfigFile().string().c_str())); + + } + } else { + strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; + } + // HTTP basic authentication - string strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]); map<string, string> mapRequestHeaders; - mapRequestHeaders["Authorization"] = string("Basic ") + strUserPass64; + mapRequestHeaders["Authorization"] = string("Basic ") + EncodeBase64(strRPCUserColonPass); // Send request string strRequest = JSONRPCRequest(strMethod, params, 1); @@ -190,6 +198,15 @@ int CommandLineRPC(int argc, char *argv[]) throw CConnectionFailed("server in warmup"); strPrint = "error: " + error.write(); nRet = abs(code); + if (error.isObject()) + { + UniValue errCode = find_value(error, "code"); + UniValue errMsg = find_value(error, "message"); + strPrint = errCode.isNull() ? "" : "error code: "+errCode.getValStr()+"\n"; + + if (errMsg.isStr()) + strPrint += "error message:\n"+errMsg.get_str(); + } } else { // Result if (result.isNull()) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 7785417518..95e20bf61b 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -16,6 +16,45 @@ using namespace std; #include "chainparamsseeds.h" +static CBlock CreateGenesisBlock(const char* pszTimestamp, CScript genesisOutputScript, uint32_t nTime=1231006505, uint32_t nNonce=2083236893, uint32_t nBits=0x1d00ffff, int32_t nVersion=1, const CAmount& genesisReward=50 * COIN) +{ + CMutableTransaction txNew; + txNew.nVersion = 1; + txNew.vin.resize(1); + txNew.vout.resize(1); + txNew.vin[0].scriptSig = CScript() << 486604799 << CScriptNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); + txNew.vout[0].nValue = genesisReward; + txNew.vout[0].scriptPubKey = genesisOutputScript; + + CBlock genesis; + genesis.nTime = nTime; + genesis.nBits = nBits; + genesis.nNonce = nNonce; + genesis.nVersion = nVersion; + genesis.vtx.push_back(txNew); + genesis.hashPrevBlock.SetNull(); + genesis.hashMerkleRoot = genesis.BuildMerkleTree(); + return genesis; +} + +/** + * Build the genesis block. Note that the output of its generation + * transaction cannot be spent since it did not originally exist in the + * database. + * + * CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1) + * CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0) + * CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73) + * CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B) + * vMerkleTree: 4a5e1e + */ +static CBlock CreateGenesisBlock(uint32_t nTime=1231006505, uint32_t nNonce=2083236893, uint32_t nBits=0x1d00ffff, int32_t nVersion=1, const CAmount& genesisReward=50 * COIN) +{ + const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"; + CScript genesisOutputScript = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; + return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward); +} + /** * Main network */ @@ -50,36 +89,9 @@ public: pchMessageStart[3] = 0xd9; vAlertPubKey = ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284"); nDefaultPort = 8333; - nMinerThreads = 0; nPruneAfterHeight = 100000; - /** - * Build the genesis block. Note that the output of its generation - * transaction cannot be spent since it did not originally exist in the - * database. - * - * CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1) - * CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0) - * CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73) - * CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B) - * vMerkleTree: 4a5e1e - */ - const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"; - CMutableTransaction txNew; - txNew.nVersion = 1; - txNew.vin.resize(1); - txNew.vout.resize(1); - txNew.vin[0].scriptSig = CScript() << 486604799 << CScriptNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); - txNew.vout[0].nValue = 50 * COIN; - txNew.vout[0].scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; - genesis.vtx.push_back(txNew); - genesis.hashPrevBlock.SetNull(); - genesis.hashMerkleRoot = genesis.BuildMerkleTree(); - genesis.nVersion = 1; - genesis.nTime = 1231006505; - genesis.nBits = 0x1d00ffff; - genesis.nNonce = 2083236893; - + genesis = CreateGenesisBlock(); consensus.hashGenesisBlock = genesis.GetHash(); assert(consensus.hashGenesisBlock == uint256S("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")); assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); @@ -99,7 +111,6 @@ public: vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_main, pnSeed6_main + ARRAYLEN(pnSeed6_main)); - fRequireRPCPassword = true; fMiningRequiresPeers = true; fDefaultConsistencyChecks = false; fRequireStandard = true; @@ -133,13 +144,17 @@ static CMainParams mainParams; /** * Testnet (v3) */ -class CTestNetParams : public CMainParams { +class CTestNetParams : public CChainParams { public: CTestNetParams() { strNetworkID = "test"; + consensus.nSubsidyHalvingInterval = 210000; consensus.nMajorityEnforceBlockUpgrade = 51; consensus.nMajorityRejectBlockOutdated = 75; consensus.nMajorityWindow = 100; + consensus.powLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks + consensus.nPowTargetSpacing = 10 * 60; consensus.fPowAllowMinDifficultyBlocks = true; pchMessageStart[0] = 0x0b; pchMessageStart[1] = 0x11; @@ -147,12 +162,9 @@ public: pchMessageStart[3] = 0x07; vAlertPubKey = ParseHex("04302390343f91cc401d56d68b123028bf52e5fca1939df127f63c6467cdf9c8e2c14b61104cf817d0b780da337893ecc4aaff1309e536162dabbdb45200ca2b0a"); nDefaultPort = 18333; - nMinerThreads = 0; nPruneAfterHeight = 1000; - //! Modify the testnet genesis block so the timestamp is valid for a later start. - genesis.nTime = 1296688602; - genesis.nNonce = 414098458; + genesis = CreateGenesisBlock(1296688602, 414098458); consensus.hashGenesisBlock = genesis.GetHash(); assert(consensus.hashGenesisBlock == uint256S("0x000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943")); @@ -171,7 +183,6 @@ public: vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_test, pnSeed6_test + ARRAYLEN(pnSeed6_test)); - fRequireRPCPassword = true; fMiningRequiresPeers = true; fDefaultConsistencyChecks = false; fRequireStandard = false; @@ -193,7 +204,7 @@ static CTestNetParams testNetParams; /** * Regression test */ -class CRegTestParams : public CTestNetParams { +class CRegTestParams : public CChainParams { public: CRegTestParams() { strNetworkID = "regtest"; @@ -202,14 +213,14 @@ public: consensus.nMajorityRejectBlockOutdated = 950; consensus.nMajorityWindow = 1000; consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks + consensus.nPowTargetSpacing = 10 * 60; + consensus.fPowAllowMinDifficultyBlocks = true; pchMessageStart[0] = 0xfa; pchMessageStart[1] = 0xbf; pchMessageStart[2] = 0xb5; pchMessageStart[3] = 0xda; - nMinerThreads = 1; - genesis.nTime = 1296688602; - genesis.nBits = 0x207fffff; - genesis.nNonce = 2; + genesis = CreateGenesisBlock(1296688602, 2, 0x207fffff); consensus.hashGenesisBlock = genesis.GetHash(); nDefaultPort = 18444; assert(consensus.hashGenesisBlock == uint256S("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")); @@ -218,7 +229,6 @@ public: vFixedSeeds.clear(); //! Regtest mode doesn't have any fixed seeds. vSeeds.clear(); //! Regtest mode doesn't have any DNS seeds. - fRequireRPCPassword = false; fMiningRequiresPeers = false; fDefaultConsistencyChecks = true; fRequireStandard = false; @@ -232,6 +242,11 @@ public: 0, 0 }; + base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,111); + base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,196); + base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,239); + base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x35)(0x87)(0xCF).convert_to_container<std::vector<unsigned char> >(); + base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x35)(0x83)(0x94).convert_to_container<std::vector<unsigned char> >(); } }; static CRegTestParams regTestParams; diff --git a/src/chainparams.h b/src/chainparams.h index 8044b553e1..66d865b620 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -50,10 +50,7 @@ public: const std::vector<unsigned char>& AlertKey() const { return vAlertPubKey; } int GetDefaultPort() const { return nDefaultPort; } - /** Used if GenerateBitcoins is called with a negative number of threads */ - int DefaultMinerThreads() const { return nMinerThreads; } const CBlock& GenesisBlock() const { return genesis; } - bool RequireRPCPassword() const { return fRequireRPCPassword; } /** Make miner wait to have peers to avoid wasting work */ bool MiningRequiresPeers() const { return fMiningRequiresPeers; } /** Default value for -checkmempool and -checkblockindex argument */ @@ -79,14 +76,12 @@ protected: //! Raw pub key bytes for the broadcast alert signing key. std::vector<unsigned char> vAlertPubKey; int nDefaultPort; - int nMinerThreads; uint64_t nPruneAfterHeight; std::vector<CDNSSeedData> vSeeds; std::vector<unsigned char> base58Prefixes[MAX_BASE58_TYPES]; std::string strNetworkID; CBlock genesis; std::vector<SeedSpec6> vFixedSeeds; - bool fRequireRPCPassword; bool fMiningRequiresPeers; bool fDefaultConsistencyChecks; bool fRequireStandard; diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp index 7d82d689ec..9c87bf2154 100644 --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -25,7 +25,7 @@ static CBaseMainParams mainParams; /** * Testnet (v3) */ -class CBaseTestNetParams : public CBaseMainParams +class CBaseTestNetParams : public CBaseChainParams { public: CBaseTestNetParams() @@ -39,11 +39,12 @@ static CBaseTestNetParams testNetParams; /* * Regression test */ -class CBaseRegTestParams : public CBaseTestNetParams +class CBaseRegTestParams : public CBaseChainParams { public: CBaseRegTestParams() { + nRPCPort = 18332; strDataDir = "regtest"; } }; diff --git a/src/coins.cpp b/src/coins.cpp index a41d5a310d..f02949de53 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -83,7 +83,7 @@ CCoinsMap::const_iterator CCoinsViewCache::FetchCoins(const uint256 &txid) const // version as fresh. ret->second.flags = CCoinsCacheEntry::FRESH; } - cachedCoinsUsage += memusage::DynamicUsage(ret->second.coins); + cachedCoinsUsage += ret->second.coins.DynamicMemoryUsage(); return ret; } @@ -110,7 +110,7 @@ CCoinsModifier CCoinsViewCache::ModifyCoins(const uint256 &txid) { ret.first->second.flags = CCoinsCacheEntry::FRESH; } } else { - cachedCoinUsage = memusage::DynamicUsage(ret.first->second.coins); + cachedCoinUsage = ret.first->second.coins.DynamicMemoryUsage(); } // Assume that whenever ModifyCoins is called, the entry will be modified. ret.first->second.flags |= CCoinsCacheEntry::DIRTY; @@ -159,7 +159,7 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn assert(it->second.flags & CCoinsCacheEntry::FRESH); CCoinsCacheEntry& entry = cacheCoins[it->first]; entry.coins.swap(it->second.coins); - cachedCoinsUsage += memusage::DynamicUsage(entry.coins); + cachedCoinsUsage += entry.coins.DynamicMemoryUsage(); entry.flags = CCoinsCacheEntry::DIRTY | CCoinsCacheEntry::FRESH; } } else { @@ -167,13 +167,13 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn // The grandparent does not have an entry, and the child is // modified and being pruned. This means we can just delete // it from the parent. - cachedCoinsUsage -= memusage::DynamicUsage(itUs->second.coins); + cachedCoinsUsage -= itUs->second.coins.DynamicMemoryUsage(); cacheCoins.erase(itUs); } else { // A normal modification. - cachedCoinsUsage -= memusage::DynamicUsage(itUs->second.coins); + cachedCoinsUsage -= itUs->second.coins.DynamicMemoryUsage(); itUs->second.coins.swap(it->second.coins); - cachedCoinsUsage += memusage::DynamicUsage(itUs->second.coins); + cachedCoinsUsage += itUs->second.coins.DynamicMemoryUsage(); itUs->second.flags |= CCoinsCacheEntry::DIRTY; } } @@ -261,6 +261,6 @@ CCoinsModifier::~CCoinsModifier() cache.cacheCoins.erase(it); } else { // If the coin still exists after the modification, add the new usage - cache.cachedCoinsUsage += memusage::DynamicUsage(it->second.coins); + cache.cachedCoinsUsage += it->second.coins.DynamicMemoryUsage(); } } diff --git a/src/coins.h b/src/coins.h index a4671645df..bf4a777b8a 100644 --- a/src/coins.h +++ b/src/coins.h @@ -7,6 +7,7 @@ #define BITCOIN_COINS_H #include "compressor.h" +#include "core_memusage.h" #include "memusage.h" #include "serialize.h" #include "uint256.h" @@ -257,8 +258,7 @@ public: size_t DynamicMemoryUsage() const { size_t ret = memusage::DynamicUsage(vout); BOOST_FOREACH(const CTxOut &out, vout) { - const std::vector<unsigned char> *script = &out.scriptPubKey; - ret += memusage::DynamicUsage(*script); + ret += RecursiveDynamicUsage(out.scriptPubKey); } return ret; } diff --git a/src/compat.h b/src/compat.h index 7a5438a11e..5378c2c761 100644 --- a/src/compat.h +++ b/src/compat.h @@ -92,4 +92,12 @@ typedef u_int SOCKET; size_t strnlen( const char *start, size_t max_len); #endif // HAVE_DECL_STRNLEN +bool static inline IsSelectableSocket(SOCKET s) { +#ifdef WIN32 + return true; +#else + return (s < FD_SETSIZE); +#endif +} + #endif // BITCOIN_COMPAT_H diff --git a/src/core_memusage.h b/src/core_memusage.h new file mode 100644 index 0000000000..711135bb44 --- /dev/null +++ b/src/core_memusage.h @@ -0,0 +1,62 @@ +// Copyright (c) 2015 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_CORE_MEMUSAGE_H +#define BITCOIN_CORE_MEMUSAGE_H + +#include "primitives/transaction.h" +#include "primitives/block.h" +#include "memusage.h" + +static inline size_t RecursiveDynamicUsage(const CScript& script) { + return memusage::DynamicUsage(*static_cast<const std::vector<unsigned char>*>(&script)); +} + +static inline size_t RecursiveDynamicUsage(const COutPoint& out) { + return 0; +} + +static inline size_t RecursiveDynamicUsage(const CTxIn& in) { + return RecursiveDynamicUsage(in.scriptSig) + RecursiveDynamicUsage(in.prevout); +} + +static inline size_t RecursiveDynamicUsage(const CTxOut& out) { + return RecursiveDynamicUsage(out.scriptPubKey); +} + +static inline size_t RecursiveDynamicUsage(const CTransaction& tx) { + size_t mem = memusage::DynamicUsage(tx.vin) + memusage::DynamicUsage(tx.vout); + for (std::vector<CTxIn>::const_iterator it = tx.vin.begin(); it != tx.vin.end(); it++) { + mem += RecursiveDynamicUsage(*it); + } + for (std::vector<CTxOut>::const_iterator it = tx.vout.begin(); it != tx.vout.end(); it++) { + mem += RecursiveDynamicUsage(*it); + } + return mem; +} + +static inline size_t RecursiveDynamicUsage(const CMutableTransaction& tx) { + size_t mem = memusage::DynamicUsage(tx.vin) + memusage::DynamicUsage(tx.vout); + for (std::vector<CTxIn>::const_iterator it = tx.vin.begin(); it != tx.vin.end(); it++) { + mem += RecursiveDynamicUsage(*it); + } + for (std::vector<CTxOut>::const_iterator it = tx.vout.begin(); it != tx.vout.end(); it++) { + mem += RecursiveDynamicUsage(*it); + } + return mem; +} + +static inline size_t RecursiveDynamicUsage(const CBlock& block) { + size_t mem = memusage::DynamicUsage(block.vtx) + memusage::DynamicUsage(block.vMerkleTree); + for (std::vector<CTransaction>::const_iterator it = block.vtx.begin(); it != block.vtx.end(); it++) { + mem += RecursiveDynamicUsage(*it); + } + return mem; +} + +static inline size_t RecursiveDynamicUsage(const CBlockLocator& locator) { + return memusage::DynamicUsage(locator.vHave); +} + +#endif // BITCOIN_CORE_MEMUSAGE_H diff --git a/src/init.cpp b/src/init.cpp index 62d5e4dbdb..ecf05d95b4 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -330,6 +330,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-whitebind=<addr>", _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6")); strUsage += HelpMessageOpt("-whitelist=<netmask>", _("Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.") + " " + _("Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway")); + strUsage += HelpMessageOpt("-whiteconnections=<n>", strprintf(_("Reserve this many inbound connections for whitelisted peers (default: %d)"), 0)); #ifdef ENABLE_WALLET strUsage += HelpMessageGroup(_("Wallet options:")); @@ -728,16 +729,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) LogPrintf("%s: parameter interaction: -zapwallettxes=<mode> -> setting -rescan=1\n", __func__); } - // Make sure enough file descriptors are available - int nBind = std::max((int)mapArgs.count("-bind") + (int)mapArgs.count("-whitebind"), 1); - nMaxConnections = GetArg("-maxconnections", 125); - nMaxConnections = std::max(std::min(nMaxConnections, (int)(FD_SETSIZE - nBind - MIN_CORE_FILEDESCRIPTORS)), 0); - int nFD = RaiseFileDescriptorLimit(nMaxConnections + MIN_CORE_FILEDESCRIPTORS); - if (nFD < MIN_CORE_FILEDESCRIPTORS) - return InitError(_("Not enough file descriptors available.")); - if (nFD - MIN_CORE_FILEDESCRIPTORS < nMaxConnections) - nMaxConnections = nFD - MIN_CORE_FILEDESCRIPTORS; - // if using block pruning, then disable txindex if (GetArg("-prune", 0)) { if (GetBoolArg("-txindex", false)) @@ -748,6 +739,47 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) } #endif } + + // Make sure enough file descriptors are available + int nBind = std::max((int)mapArgs.count("-bind") + (int)mapArgs.count("-whitebind"), 1); + int nUserMaxConnections = GetArg("-maxconnections", 125); + nMaxConnections = std::max(nUserMaxConnections, 0); + int nUserWhiteConnections = GetArg("-whiteconnections", 0); + nWhiteConnections = std::max(nUserWhiteConnections, 0); + + if ((mapArgs.count("-whitelist")) || (mapArgs.count("-whitebind"))) { + if (!(mapArgs.count("-maxconnections"))) { + // User is using whitelist feature, + // but did not specify -maxconnections parameter. + // Silently increase the default to compensate, + // so that the whitelist connection reservation feature + // does not inadvertently reduce the default + // inbound connection capacity of the network. + nMaxConnections += nWhiteConnections; + } + } else { + // User not using whitelist feature. + // Silently disable connection reservation, + // for the same reason as above. + nWhiteConnections = 0; + } + + // Trim requested connection counts, to fit into system limitations + nMaxConnections = std::max(std::min(nMaxConnections, (int)(FD_SETSIZE - nBind - MIN_CORE_FILEDESCRIPTORS)), 0); + int nFD = RaiseFileDescriptorLimit(nMaxConnections + MIN_CORE_FILEDESCRIPTORS); + if (nFD < MIN_CORE_FILEDESCRIPTORS) + return InitError(_("Not enough file descriptors available.")); + nMaxConnections = std::min(nFD - MIN_CORE_FILEDESCRIPTORS, nMaxConnections); + + if (nMaxConnections < nUserMaxConnections) + InitWarning(strprintf(_("Reducing -maxconnections from %d to %d, because of system limitations."), nUserMaxConnections, nMaxConnections)); + + // Connection capacity is prioritized in this order: + // outbound connections (hardcoded to 8), + // then whitelisted connections, + // then non-whitelisted connections get whatever's left (if any). + if ((nWhiteConnections > 0) && (nWhiteConnections >= (nMaxConnections - 8))) + InitWarning(strprintf(_("All non-whitelisted incoming connections will be dropped, because -whiteconnections is %d and -maxconnections is only %d."), nWhiteConnections, nMaxConnections)); // ********************************************************* Step 3: parameter-to-internal-flags @@ -926,6 +958,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) LogPrintf("Using data directory %s\n", strDataDir); LogPrintf("Using config file %s\n", GetConfigFile().string()); LogPrintf("Using at most %i connections (%i file descriptors available)\n", nMaxConnections, nFD); + if (nWhiteConnections > 0) + LogPrintf("Reserving %i of these connections for whitelisted inbound peers\n", nWhiteConnections); std::ostringstream strErrors; LogPrintf("Using %u threads for script verification\n", nScriptCheckThreads); diff --git a/src/main.cpp b/src/main.cpp index 03c09f0a27..fb90d7578c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2059,7 +2059,6 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * LogPrint("bench", " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * 0.001, nTimeReadFromDisk * 0.000001); { CCoinsViewCache view(pcoinsTip); - CInv inv(MSG_BLOCK, pindexNew->GetBlockHash()); bool rv = ConnectBlock(*pblock, state, pindexNew, view); GetMainSignals().BlockChecked(*pblock, state); if (!rv) { @@ -2067,7 +2066,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * InvalidBlockFound(pindexNew, state); return error("ConnectTip(): ConnectBlock %s failed", pindexNew->GetBlockHash().ToString()); } - mapBlockSource.erase(inv.hash); + mapBlockSource.erase(pindexNew->GetBlockHash()); nTime3 = GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2; LogPrint("bench", " - Connect total: %.2fms [%.2fs]\n", (nTime3 - nTime2) * 0.001, nTimeConnectTotal * 0.000001); assert(view.Flush()); diff --git a/src/memusage.h b/src/memusage.h index 9f7de9e2e1..be3964df1b 100644 --- a/src/memusage.h +++ b/src/memusage.h @@ -11,6 +11,7 @@ #include <set> #include <vector> +#include <boost/foreach.hpp> #include <boost/unordered_set.hpp> #include <boost/unordered_map.hpp> @@ -20,19 +21,27 @@ namespace memusage /** Compute the total memory used by allocating alloc bytes. */ static size_t MallocUsage(size_t alloc); +/** Dynamic memory usage for built-in types is zero. */ +static inline size_t DynamicUsage(const int8_t& v) { return 0; } +static inline size_t DynamicUsage(const uint8_t& v) { return 0; } +static inline size_t DynamicUsage(const int16_t& v) { return 0; } +static inline size_t DynamicUsage(const uint16_t& v) { return 0; } +static inline size_t DynamicUsage(const int32_t& v) { return 0; } +static inline size_t DynamicUsage(const uint32_t& v) { return 0; } +static inline size_t DynamicUsage(const int64_t& v) { return 0; } +static inline size_t DynamicUsage(const uint64_t& v) { return 0; } +static inline size_t DynamicUsage(const float& v) { return 0; } +static inline size_t DynamicUsage(const double& v) { return 0; } +template<typename X> static inline size_t DynamicUsage(X * const &v) { return 0; } +template<typename X> static inline size_t DynamicUsage(const X * const &v) { return 0; } + /** Compute the memory used for dynamically allocated but owned data structures. * For generic data types, this is *not* recursive. DynamicUsage(vector<vector<int> >) * will compute the memory used for the vector<int>'s, but not for the ints inside. * This is for efficiency reasons, as these functions are intended to be fast. If * application data structures require more accurate inner accounting, they should - * do the recursion themselves, or use more efficient caching + updating on modification. + * iterate themselves, or use more efficient caching + updating on modification. */ -template<typename X> static size_t DynamicUsage(const std::vector<X>& v); -template<typename X> static size_t DynamicUsage(const std::set<X>& s); -template<typename X, typename Y> static size_t DynamicUsage(const std::map<X, Y>& m); -template<typename X, typename Y> static size_t DynamicUsage(const boost::unordered_set<X, Y>& s); -template<typename X, typename Y, typename Z> static size_t DynamicUsage(const boost::unordered_map<X, Y, Z>& s); -template<typename X> static size_t DynamicUsage(const X& x); static inline size_t MallocUsage(size_t alloc) { @@ -98,14 +107,6 @@ static inline size_t DynamicUsage(const boost::unordered_map<X, Y, Z>& m) return MallocUsage(sizeof(boost_unordered_node<std::pair<const X, Y> >)) * m.size() + MallocUsage(sizeof(void*) * m.bucket_count()); } -// Dispatch to class method as fallback - -template<typename X> -static inline size_t DynamicUsage(const X& x) -{ - return x.DynamicMemoryUsage(); -} - } #endif diff --git a/src/miner.cpp b/src/miner.cpp index bdb85c8c79..5e575f45f1 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -542,13 +542,8 @@ void GenerateBitcoins(bool fGenerate, int nThreads, const CChainParams& chainpar { static boost::thread_group* minerThreads = NULL; - if (nThreads < 0) { - // In regtest threads defaults to 1 - if (Params().DefaultMinerThreads()) - nThreads = Params().DefaultMinerThreads(); - else - nThreads = GetNumCores(); - } + if (nThreads < 0) + nThreads = GetNumCores(); if (minerThreads != NULL) { diff --git a/src/net.cpp b/src/net.cpp index 950311ee3a..3d369c7dd1 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -79,6 +79,7 @@ uint64_t nLocalHostNonce = 0; static std::vector<ListenSocket> vhListenSocket; CAddrMan addrman; int nMaxConnections = 125; +int nWhiteConnections = 0; bool fAddressesInitialized = false; vector<CNode*> vNodes; @@ -385,6 +386,12 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest) if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, Params().GetDefaultPort(), nConnectTimeout, &proxyConnectionFailed) : ConnectSocket(addrConnect, hSocket, nConnectTimeout, &proxyConnectionFailed)) { + if (!IsSelectableSocket(hSocket)) { + LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n"); + CloseSocket(hSocket); + return NULL; + } + addrman.Attempt(addrConnect); // Add node @@ -928,6 +935,7 @@ void ThreadSocketHandler() SOCKET hSocket = accept(hListenSocket.socket, (struct sockaddr*)&sockaddr, &len); CAddress addr; int nInbound = 0; + int nMaxInbound = nMaxConnections - MAX_OUTBOUND_CONNECTIONS; if (hSocket != INVALID_SOCKET) if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr)) @@ -947,8 +955,19 @@ void ThreadSocketHandler() if (nErr != WSAEWOULDBLOCK) LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr)); } - else if (nInbound >= nMaxConnections - MAX_OUTBOUND_CONNECTIONS) + else if (!IsSelectableSocket(hSocket)) + { + LogPrintf("connection from %s dropped: non-selectable socket\n", addr.ToString()); + CloseSocket(hSocket); + } + else if (nInbound >= nMaxInbound) + { + LogPrint("net", "connection from %s dropped (full)\n", addr.ToString()); + CloseSocket(hSocket); + } + else if (!whitelisted && (nInbound >= (nMaxInbound - nWhiteConnections))) { + LogPrint("net", "connection from %s dropped (non-whitelisted)\n", addr.ToString()); CloseSocket(hSocket); } else if (CNode::IsBanned(addr) && !whitelisted) @@ -962,6 +981,8 @@ void ThreadSocketHandler() pnode->AddRef(); pnode->fWhitelisted = whitelisted; + LogPrint("net", "connection from %s accepted\n", addr.ToString()); + { LOCK(cs_vNodes); vNodes.push_back(pnode); @@ -1587,6 +1608,13 @@ bool BindListenPort(const CService &addrBind, string& strError, bool fWhiteliste LogPrintf("%s\n", strError); return false; } + if (!IsSelectableSocket(hListenSocket)) + { + strError = "Error: Couldn't create a listenable socket for incoming connections"; + LogPrintf("%s\n", strError); + return false; + } + #ifndef WIN32 #ifdef SO_NOSIGPIPE @@ -2295,4 +2323,4 @@ void DumpBanlist() LogPrint("net", "Flushed %d banned node ips/subnets to banlist.dat %dms\n", banmap.size(), GetTimeMillis() - nStart); -}
\ No newline at end of file +} @@ -141,7 +141,20 @@ extern bool fListen; extern uint64_t nLocalServices; extern uint64_t nLocalHostNonce; extern CAddrMan addrman; + +// The allocation of connections against the maximum allowed (nMaxConnections) +// is prioritized as follows: +// 1st: Outbound connections (MAX_OUTBOUND_CONNECTIONS) +// 2nd: Inbound connections from whitelisted peers (nWhiteConnections) +// 3rd: Inbound connections from non-whitelisted peers +// Thus, the number of connection slots for the general public to use is: +// nMaxConnections - (MAX_OUTBOUND_CONNECTIONS + nWhiteConnections) +// Any additional inbound connections beyond limits will be immediately closed + +/** Maximum number of connections to simultaneously allow (aka connection slots) */ extern int nMaxConnections; +/** Number of connection slots to reserve for inbound from whitelisted peers */ +extern int nWhiteConnections; extern std::vector<CNode*> vNodes; extern CCriticalSection cs_vNodes; diff --git a/src/netbase.cpp b/src/netbase.cpp index c9fc7d67f7..b7e2e57917 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -266,6 +266,9 @@ bool static InterruptibleRecv(char* data, size_t len, int timeout, SOCKET& hSock } else { // Other error or blocking int nErr = WSAGetLastError(); if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL) { + if (!IsSelectableSocket(hSocket)) { + return false; + } struct timeval tval = MillisToTimeval(std::min(endTime - curTime, maxWait)); fd_set fdset; FD_ZERO(&fdset); diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index 6cfd93a9a1..2a457cdae7 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -141,10 +141,13 @@ public: // which has units satoshis-per-kilobyte. // If you'd pay more than 1/3 in fees // to spend something, then we consider it dust. - // A typical txout is 34 bytes big, and will + // A typical spendable txout is 34 bytes big, and will // need a CTxIn of at least 148 bytes to spend: - // so dust is a txout less than 546 satoshis + // so dust is a spendable txout less than 546 satoshis // with default minRelayTxFee. + if (scriptPubKey.IsUnspendable()) + return 0; + size_t nSize = GetSerializeSize(SER_DISK,0)+148u; return 3*minRelayTxFee.GetFee(nSize); } diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index 5485d89f3e..af6801919c 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -254,8 +254,7 @@ void AddressBookPage::done(int retval) // Figure out which address was selected, and return it QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address); - foreach (QModelIndex index, indexes) - { + Q_FOREACH (const QModelIndex& index, indexes) { QVariant address = table->model()->data(index); returnValue = address.toString(); } diff --git a/src/qt/addressbookpage.h b/src/qt/addressbookpage.h index 5105f09ced..09634ce336 100644 --- a/src/qt/addressbookpage.h +++ b/src/qt/addressbookpage.h @@ -45,7 +45,7 @@ public: void setModel(AddressTableModel *model); const QString &getReturnValue() const { return returnValue; } -public slots: +public Q_SLOTS: void done(int retval); private: @@ -59,7 +59,7 @@ private: QAction *deleteAction; // to be able to explicitly disable it QString newAddressToSelect; -private slots: +private Q_SLOTS: /** Delete currently selected address entry */ void on_deleteAddress_clicked(); /** Create a new address for receiving coins and / or add a new address book entry */ @@ -80,7 +80,7 @@ private slots: /** New entry/entries were added to address table */ void selectNewAddress(const QModelIndex &parent, int begin, int /*end*/); -signals: +Q_SIGNALS: void sendCoins(QString addr); }; diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index 8e20836c65..c5ac07cfc2 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -450,5 +450,5 @@ int AddressTableModel::lookupAddress(const QString &address) const void AddressTableModel::emitDataChanged(int idx) { - emit dataChanged(index(idx, 0, QModelIndex()), index(idx, columns.length()-1, QModelIndex())); + Q_EMIT dataChanged(index(idx, 0, QModelIndex()), index(idx, columns.length()-1, QModelIndex())); } diff --git a/src/qt/addresstablemodel.h b/src/qt/addresstablemodel.h index 6b34b2eac2..2b7475c4e2 100644 --- a/src/qt/addresstablemodel.h +++ b/src/qt/addresstablemodel.h @@ -84,7 +84,7 @@ private: /** Notify listeners that data changed. */ void emitDataChanged(int index); -public slots: +public Q_SLOTS: /* Update address list from core. */ void updateEntry(const QString &address, const QString &label, bool isMine, const QString &purpose, int status); diff --git a/src/qt/askpassphrasedialog.h b/src/qt/askpassphrasedialog.h index 74d54d18f7..d4d832825a 100644 --- a/src/qt/askpassphrasedialog.h +++ b/src/qt/askpassphrasedialog.h @@ -40,7 +40,7 @@ private: WalletModel *model; bool fCapsLock; -private slots: +private Q_SLOTS: void textChanged(); protected: diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 8740b98b70..ec02c4be9f 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -48,6 +48,7 @@ #include <QThread> #include <QTimer> #include <QTranslator> +#include <QSslConfiguration> #if defined(QT_STATICPLUGIN) #include <QtPlugin> @@ -168,11 +169,11 @@ class BitcoinCore: public QObject public: explicit BitcoinCore(); -public slots: +public Q_SLOTS: void initialize(); void shutdown(); -signals: +Q_SIGNALS: void initializeResult(int retval); void shutdownResult(int retval); void runawayException(const QString &message); @@ -215,13 +216,13 @@ public: /// Get window identifier of QMainWindow (BitcoinGUI) WId getMainWinId() const; -public slots: +public Q_SLOTS: void initializeResult(int retval); void shutdownResult(int retval); /// Handle runaway exceptions. Shows a message box with the problem and quits the program. void handleRunawayException(const QString &message); -signals: +Q_SIGNALS: void requestedInitialize(); void requestedShutdown(); void stopThread(); @@ -252,7 +253,7 @@ BitcoinCore::BitcoinCore(): void BitcoinCore::handleRunawayException(const std::exception *e) { PrintExceptionContinue(e, "Runaway exception"); - emit runawayException(QString::fromStdString(strMiscWarning)); + Q_EMIT runawayException(QString::fromStdString(strMiscWarning)); } void BitcoinCore::initialize() @@ -268,7 +269,7 @@ void BitcoinCore::initialize() */ StartDummyRPCThread(); } - emit initializeResult(rv); + Q_EMIT initializeResult(rv); } catch (const std::exception& e) { handleRunawayException(&e); } catch (...) { @@ -285,7 +286,7 @@ void BitcoinCore::shutdown() threadGroup.join_all(); Shutdown(); qDebug() << __func__ << ": Shutdown finished"; - emit shutdownResult(1); + Q_EMIT shutdownResult(1); } catch (const std::exception& e) { handleRunawayException(&e); } catch (...) { @@ -314,7 +315,7 @@ BitcoinApplication::~BitcoinApplication() if(coreThread) { qDebug() << __func__ << ": Stopping thread"; - emit stopThread(); + Q_EMIT stopThread(); coreThread->wait(); qDebug() << __func__ << ": Stopped thread"; } @@ -385,7 +386,7 @@ void BitcoinApplication::requestInitialize() { qDebug() << __func__ << ": Requesting initialize"; startThread(); - emit requestedInitialize(); + Q_EMIT requestedInitialize(); } void BitcoinApplication::requestShutdown() @@ -408,7 +409,7 @@ void BitcoinApplication::requestShutdown() ShutdownWindow::showShutdownWindow(window); // Request shutdown from core thread - emit requestedShutdown(); + Q_EMIT requestedShutdown(); } void BitcoinApplication::initializeResult(int retval) @@ -448,7 +449,7 @@ void BitcoinApplication::initializeResult(int retval) { window->show(); } - emit splashFinished(window); + Q_EMIT splashFinished(window); #ifdef ENABLE_WALLET // Now that initialization/startup is done, process any command-line @@ -515,6 +516,13 @@ int main(int argc, char *argv[]) #ifdef Q_OS_MAC QApplication::setAttribute(Qt::AA_DontShowIconsInMenus); #endif +#if QT_VERSION >= 0x050500 + // Because of the POODLE attack it is recommended to disable SSLv3 (https://disablessl3.com/), + // so set SSL protocols to TLS1.0+. + QSslConfiguration sslconf = QSslConfiguration::defaultConfiguration(); + sslconf.setProtocol(QSsl::TlsV1_0OrLater); + QSslConfiguration::setDefaultConfiguration(sslconf); +#endif // Register meta types used for QMetaObject::invokeMethod qRegisterMetaType< bool* >(); diff --git a/src/qt/bitcoinamountfield.cpp b/src/qt/bitcoinamountfield.cpp index d31a1e018b..d19b9fd4af 100644 --- a/src/qt/bitcoinamountfield.cpp +++ b/src/qt/bitcoinamountfield.cpp @@ -61,7 +61,7 @@ public: void setValue(const CAmount& value) { lineEdit()->setText(BitcoinUnits::format(currentUnit, value, false, BitcoinUnits::separatorAlways)); - emit valueChanged(); + Q_EMIT valueChanged(); } void stepBy(int steps) @@ -184,7 +184,7 @@ protected: return rv; } -signals: +Q_SIGNALS: void valueChanged(); }; diff --git a/src/qt/bitcoinamountfield.h b/src/qt/bitcoinamountfield.h index b047e6c51a..3703b1f8d7 100644 --- a/src/qt/bitcoinamountfield.h +++ b/src/qt/bitcoinamountfield.h @@ -56,7 +56,7 @@ public: */ QWidget *setupTabChain(QWidget *prev); -signals: +Q_SIGNALS: void valueChanged(); protected: @@ -67,7 +67,7 @@ private: AmountSpinBox *amount; QValueComboBox *unit; -private slots: +private Q_SLOTS: void unitChanged(int idx); }; diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index efba0f5e18..396435f12b 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -600,7 +600,7 @@ void BitcoinGUI::openClicked() OpenURIDialog dlg(this); if(dlg.exec()) { - emit receivedURI(dlg.getURI()); + Q_EMIT receivedURI(dlg.getURI()); } } @@ -886,9 +886,9 @@ void BitcoinGUI::dropEvent(QDropEvent *event) { if(event->mimeData()->hasUrls()) { - foreach(const QUrl &uri, event->mimeData()->urls()) + Q_FOREACH(const QUrl &uri, event->mimeData()->urls()) { - emit receivedURI(uri.toString()); + Q_EMIT receivedURI(uri.toString()); } } event->acceptProposedAction(); @@ -1050,7 +1050,7 @@ UnitDisplayStatusBarControl::UnitDisplayStatusBarControl() : QList<BitcoinUnits::Unit> units = BitcoinUnits::availableUnits(); int max_width = 0; const QFontMetrics fm(font()); - foreach (const BitcoinUnits::Unit unit, units) + Q_FOREACH (const BitcoinUnits::Unit unit, units) { max_width = qMax(max_width, fm.width(BitcoinUnits::name(unit))); } @@ -1069,7 +1069,7 @@ void UnitDisplayStatusBarControl::mousePressEvent(QMouseEvent *event) void UnitDisplayStatusBarControl::createContextMenu() { menu = new QMenu(); - foreach(BitcoinUnits::Unit u, BitcoinUnits::availableUnits()) + Q_FOREACH(BitcoinUnits::Unit u, BitcoinUnits::availableUnits()) { QAction *menuAction = new QAction(QString(BitcoinUnits::name(u)), this); menuAction->setData(QVariant(u)); diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 494541f002..4e50b1712a 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -136,11 +136,11 @@ private: /** Disconnect core signals from GUI client */ void unsubscribeFromCoreSignals(); -signals: +Q_SIGNALS: /** Signal raised when a URI was entered or dragged to the GUI */ void receivedURI(const QString &uri); -public slots: +public Q_SLOTS: /** Set number of connections shown in the UI */ void setNumConnections(int count); /** Set number of blocks and last block date shown in the UI */ @@ -168,7 +168,7 @@ public slots: void incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label); #endif // ENABLE_WALLET -private slots: +private Q_SLOTS: #ifdef ENABLE_WALLET /** Switch to overview (home) page */ void gotoOverviewPage(); @@ -232,7 +232,7 @@ private: /** Creates context menu, its actions, and wires up all the relevant signals for mouse events. */ void createContextMenu(); -private slots: +private Q_SLOTS: /** When Display Units are changed on OptionsModel it will refresh the display text of the control on the status bar */ void updateDisplayUnit(int newUnits); /** Tells underlying optionsModel to update its current display unit. */ diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 8e29cdeb06..92a9ef279d 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -53,9 +53,9 @@ int ClientModel::getNumConnections(unsigned int flags) const return vNodes.size(); int nNum = 0; - BOOST_FOREACH(CNode* pnode, vNodes) - if (flags & (pnode->fInbound ? CONNECTIONS_IN : CONNECTIONS_OUT)) - nNum++; + BOOST_FOREACH(const CNode* pnode, vNodes) + if (flags & (pnode->fInbound ? CONNECTIONS_IN : CONNECTIONS_OUT)) + nNum++; return nNum; } @@ -117,15 +117,15 @@ void ClientModel::updateTimer() cachedReindexing = fReindex; cachedImporting = fImporting; - emit numBlocksChanged(newNumBlocks, newBlockDate); + Q_EMIT numBlocksChanged(newNumBlocks, newBlockDate); } - emit bytesChanged(getTotalBytesRecv(), getTotalBytesSent()); + Q_EMIT bytesChanged(getTotalBytesRecv(), getTotalBytesSent()); } void ClientModel::updateNumConnections(int numConnections) { - emit numConnectionsChanged(numConnections); + Q_EMIT numConnectionsChanged(numConnections); } void ClientModel::updateAlert(const QString &hash, int status) @@ -138,11 +138,11 @@ void ClientModel::updateAlert(const QString &hash, int status) CAlert alert = CAlert::getAlertByHash(hash_256); if(!alert.IsNull()) { - emit message(tr("Network Alert"), QString::fromStdString(alert.strStatusBar), CClientUIInterface::ICON_ERROR); + Q_EMIT message(tr("Network Alert"), QString::fromStdString(alert.strStatusBar), CClientUIInterface::ICON_ERROR); } } - emit alertsChanged(getStatusBarWarnings()); + Q_EMIT alertsChanged(getStatusBarWarnings()); } bool ClientModel::inInitialBlockDownload() const diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index 214701810c..68434f404c 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -82,7 +82,7 @@ private: void subscribeToCoreSignals(); void unsubscribeFromCoreSignals(); -signals: +Q_SIGNALS: void numConnectionsChanged(int count); void numBlocksChanged(int count, const QDateTime& blockDate); void alertsChanged(const QString &warnings); @@ -94,7 +94,7 @@ signals: // Show progress dialog e.g. for verifychain void showProgress(const QString &title, int nProgress); -public slots: +public Q_SLOTS: void updateTimer(); void updateNumConnections(int numConnections); void updateAlert(const QString &hash, int status); diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 7531fbddcb..778dbcb1ca 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -30,7 +30,6 @@ #include <QTreeWidget> #include <QTreeWidgetItem> -using namespace std; QList<CAmount> CoinControlDialog::payAmounts; CCoinControl* CoinControlDialog::coinControl = new CCoinControl(); bool CoinControlDialog::fSubtractFeeFromAmount = false; @@ -118,7 +117,7 @@ CoinControlDialog::CoinControlDialog(QWidget *parent) : // (un)select all connect(ui->pushButtonSelectAll, SIGNAL(clicked()), this, SLOT(buttonSelectAllClicked())); - // change coin control first column label due Qt4 bug. + // change coin control first column label due Qt4 bug. // see https://github.com/bitcoin/bitcoin/issues/5716 ui->treeWidget->headerItem()->setText(COLUMN_CHECKBOX, QString()); @@ -442,7 +441,7 @@ QString CoinControlDialog::getPriorityLabel(double dPriority, double mempoolEsti // shows count of locked unspent outputs void CoinControlDialog::updateLabelLocked() { - vector<COutPoint> vOutpts; + std::vector<COutPoint> vOutpts; model->listLockedCoins(vOutpts); if (vOutpts.size() > 0) { @@ -461,13 +460,13 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) CAmount nPayAmount = 0; bool fDust = false; CMutableTransaction txDummy; - foreach(const CAmount &amount, CoinControlDialog::payAmounts) + Q_FOREACH(const CAmount &amount, CoinControlDialog::payAmounts) { nPayAmount += amount; if (amount > 0) { - CTxOut txout(amount, (CScript)vector<unsigned char>(24, 0)); + CTxOut txout(amount, (CScript)std::vector<unsigned char>(24, 0)); txDummy.vout.push_back(txout); if (txout.IsDust(::minRelayTxFee)) fDust = true; @@ -487,13 +486,12 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) int nQuantityUncompressed = 0; bool fAllowFree = false; - vector<COutPoint> vCoinControl; - vector<COutput> vOutputs; + std::vector<COutPoint> vCoinControl; + std::vector<COutput> vOutputs; coinControl->ListSelected(vCoinControl); model->getOutputs(vCoinControl, vOutputs); - BOOST_FOREACH(const COutput& out, vOutputs) - { + BOOST_FOREACH(const COutput& out, vOutputs) { // unselect already spent, very unlikely scenario, this could happen // when selected are spent elsewhere, like rpc or another computer uint256 txhash = out.tx->GetHash(); @@ -569,7 +567,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) // Never create dust outputs; if we would, just add the dust to the fee. if (nChange > 0 && nChange < CENT) { - CTxOut txout(nChange, (CScript)vector<unsigned char>(24, 0)); + CTxOut txout(nChange, (CScript)std::vector<unsigned char>(24, 0)); if (txout.IsDust(::minRelayTxFee)) { if (CoinControlDialog::fSubtractFeeFromAmount) // dust-change will be raised until no dust @@ -688,11 +686,10 @@ void CoinControlDialog::updateView() int nDisplayUnit = model->getOptionsModel()->getDisplayUnit(); double mempoolEstimatePriority = mempool.estimatePriority(nTxConfirmTarget); - map<QString, vector<COutput> > mapCoins; + std::map<QString, std::vector<COutput> > mapCoins; model->listCoins(mapCoins); - BOOST_FOREACH(PAIRTYPE(QString, vector<COutput>) coins, mapCoins) - { + BOOST_FOREACH(const PAIRTYPE(QString, std::vector<COutput>)& coins, mapCoins) { QTreeWidgetItem *itemWalletAddress = new QTreeWidgetItem(); itemWalletAddress->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked); QString sWalletAddress = coins.first; @@ -719,8 +716,7 @@ void CoinControlDialog::updateView() double dPrioritySum = 0; int nChildren = 0; int nInputSum = 0; - BOOST_FOREACH(const COutput& out, coins.second) - { + BOOST_FOREACH(const COutput& out, coins.second) { int nInputSize = 0; nSum += out.tx->vout[out.i].nValue; nChildren++; diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h index 5ec382838f..0566b02c96 100644 --- a/src/qt/coincontroldialog.h +++ b/src/qt/coincontroldialog.h @@ -102,7 +102,7 @@ private: return column; } -private slots: +private Q_SLOTS: void showMenu(const QPoint &); void copyAmount(); void copyLabel(); diff --git a/src/qt/editaddressdialog.h b/src/qt/editaddressdialog.h index 13c6da8eda..d59fce2d41 100644 --- a/src/qt/editaddressdialog.h +++ b/src/qt/editaddressdialog.h @@ -40,7 +40,7 @@ public: QString getAddress() const; void setAddress(const QString &address); -public slots: +public Q_SLOTS: void accept(); private: diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index 55df64a256..0ac3db6327 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -169,7 +169,7 @@ namespace GUIUtil void setViewHeaderResizeMode(int logicalIndex, QHeaderView::ResizeMode resizeMode); void resizeColumn(int nColumnIndex, int width); - private slots: + private Q_SLOTS: void on_sectionResized(int logicalIndex, int oldSize, int newSize); void on_geometriesChanged(); }; diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index 9f72602b4d..117969758c 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -42,10 +42,10 @@ public: ST_ERROR }; -public slots: +public Q_SLOTS: void check(); -signals: +Q_SIGNALS: void reply(int status, const QString &message, quint64 available); private: @@ -102,7 +102,7 @@ void FreespaceChecker::check() replyStatus = ST_ERROR; replyMessage = tr("Cannot create data directory here."); } - emit reply(replyStatus, replyMessage, freeBytesAvailable); + Q_EMIT reply(replyStatus, replyMessage, freeBytesAvailable); } @@ -121,7 +121,7 @@ Intro::~Intro() { delete ui; /* Ensure thread is finished before it is deleted */ - emit stopThread(); + Q_EMIT stopThread(); thread->wait(); } @@ -277,7 +277,7 @@ void Intro::checkPath(const QString &dataDir) if(!signalled) { signalled = true; - emit requestCheck(); + Q_EMIT requestCheck(); } mutex.unlock(); } diff --git a/src/qt/intro.h b/src/qt/intro.h index c9735615b6..50783f7225 100644 --- a/src/qt/intro.h +++ b/src/qt/intro.h @@ -43,14 +43,14 @@ public: */ static QString getDefaultDataDirectory(); -signals: +Q_SIGNALS: void requestCheck(); void stopThread(); -public slots: +public Q_SLOTS: void setStatus(int status, const QString &message, quint64 bytesAvailable); -private slots: +private Q_SLOTS: void on_dataDirectory_textChanged(const QString &arg1); void on_ellipsisButton_clicked(); void on_dataDirDefault_clicked(); diff --git a/src/qt/macdockiconhandler.h b/src/qt/macdockiconhandler.h index 15a6583ca4..8bd867c103 100644 --- a/src/qt/macdockiconhandler.h +++ b/src/qt/macdockiconhandler.h @@ -30,7 +30,7 @@ public: static void cleanup(); void handleDockIconClickEvent(); -signals: +Q_SIGNALS: void dockIconClicked(); private: diff --git a/src/qt/macdockiconhandler.mm b/src/qt/macdockiconhandler.mm index 58a0365d3d..a41d39d51e 100644 --- a/src/qt/macdockiconhandler.mm +++ b/src/qt/macdockiconhandler.mm @@ -130,5 +130,5 @@ void MacDockIconHandler::handleDockIconClickEvent() this->mainWindow->show(); } - emit this->dockIconClicked(); + Q_EMIT this->dockIconClicked(); } diff --git a/src/qt/notificator.h b/src/qt/notificator.h index 182e948c7d..f2a15e9c34 100644 --- a/src/qt/notificator.h +++ b/src/qt/notificator.h @@ -40,7 +40,7 @@ public: Critical /**< An error occurred */ }; -public slots: +public Q_SLOTS: /** Show notification message. @param[in] cls general message class @param[in] title title shown with message diff --git a/src/qt/openuridialog.h b/src/qt/openuridialog.h index d5c434ba9c..28b8f56ca6 100644 --- a/src/qt/openuridialog.h +++ b/src/qt/openuridialog.h @@ -21,10 +21,10 @@ public: QString getURI(); -protected slots: +protected Q_SLOTS: void accept(); -private slots: +private Q_SLOTS: void on_selectFileButton_clicked(); private: diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 87c727335e..173bed3b62 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -73,7 +73,7 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : /* Display elements init */ QDir translations(":translations"); ui->lang->addItem(QString("(") + tr("default") + QString(")"), QVariant("")); - foreach(const QString &langStr, translations.entryList()) + Q_FOREACH(const QString &langStr, translations.entryList()) { QLocale locale(langStr); @@ -281,7 +281,7 @@ bool OptionsDialog::eventFilter(QObject *object, QEvent *event) { if(object == ui->proxyIp) { - emit proxyIpChecks(ui->proxyIp, ui->proxyPort->text().toInt()); + Q_EMIT proxyIpChecks(ui->proxyIp, ui->proxyPort->text().toInt()); } } return QDialog::eventFilter(object, event); diff --git a/src/qt/optionsdialog.h b/src/qt/optionsdialog.h index f4e5157595..fa983e798c 100644 --- a/src/qt/optionsdialog.h +++ b/src/qt/optionsdialog.h @@ -33,7 +33,7 @@ public: protected: bool eventFilter(QObject *object, QEvent *event); -private slots: +private Q_SLOTS: /* enable OK button */ void enableOkButton(); /* disable OK button */ @@ -48,7 +48,7 @@ private slots: void clearStatusLabel(); void doProxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort); -signals: +Q_SIGNALS: void proxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort); private: diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 41d6acf358..b4ce8191d0 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -286,7 +286,7 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in case CoinControlFeatures: fCoinControlFeatures = value.toBool(); settings.setValue("fCoinControlFeatures", fCoinControlFeatures); - emit coinControlFeaturesChanged(fCoinControlFeatures); + Q_EMIT coinControlFeaturesChanged(fCoinControlFeatures); break; case DatabaseCache: if (settings.value("nDatabaseCache") != value) { @@ -311,7 +311,7 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in } } - emit dataChanged(index, index); + Q_EMIT dataChanged(index, index); return successful; } @@ -324,7 +324,7 @@ void OptionsModel::setDisplayUnit(const QVariant &value) QSettings settings; nDisplayUnit = value.toInt(); settings.setValue("nDisplayUnit", nDisplayUnit); - emit displayUnitChanged(nDisplayUnit); + Q_EMIT displayUnitChanged(nDisplayUnit); } } diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h index bf892768ed..fc26d65b04 100644 --- a/src/qt/optionsmodel.h +++ b/src/qt/optionsmodel.h @@ -81,7 +81,7 @@ private: /// Add option to list of GUI options overridden through command line/config file void addOverriddenOption(const std::string &option); -signals: +Q_SIGNALS: void displayUnitChanged(int unit); void coinControlFeaturesChanged(bool); }; diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 2e33b9adf8..bbd95ef478 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -142,7 +142,7 @@ OverviewPage::OverviewPage(QWidget *parent) : void OverviewPage::handleTransactionClicked(const QModelIndex &index) { if(filter) - emit transactionClicked(filter->mapToSource(index)); + Q_EMIT transactionClicked(filter->mapToSource(index)); } OverviewPage::~OverviewPage() diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h index 64cb1dc4e0..de5ac345da 100644 --- a/src/qt/overviewpage.h +++ b/src/qt/overviewpage.h @@ -35,11 +35,11 @@ public: void setWalletModel(WalletModel *walletModel); void showOutOfSyncWarning(bool fShow); -public slots: +public Q_SLOTS: void setBalance(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance, const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance); -signals: +Q_SIGNALS: void transactionClicked(const QModelIndex &index); private: @@ -56,7 +56,7 @@ private: TxViewDelegate *txdelegate; TransactionFilterProxy *filter; -private slots: +private Q_SLOTS: void updateDisplayUnit(); void handleTransactionClicked(const QModelIndex &index); void updateAlerts(const QString &warnings); diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp index 7e9729eeb9..78a783dea4 100644 --- a/src/qt/paymentrequestplus.cpp +++ b/src/qt/paymentrequestplus.cpp @@ -19,8 +19,6 @@ #include <QDebug> #include <QSslCertificate> -using namespace std; - class SSLVerifyError : public std::runtime_error { public: @@ -49,7 +47,7 @@ bool PaymentRequestPlus::parse(const QByteArray& data) return true; } -bool PaymentRequestPlus::SerializeToString(string* output) const +bool PaymentRequestPlus::SerializeToString(std::string* output) const { return paymentRequest.SerializeToString(output); } diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 09e9949b10..6481b0046e 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -46,8 +46,6 @@ #include <QUrlQuery> #endif -using namespace std; - const int BITCOIN_IPC_CONNECT_TIMEOUT = 1000; // milliseconds const QString BITCOIN_IPC_PREFIX("bitcoin:"); // BIP70 payment protocol messages @@ -148,7 +146,7 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store) int nRootCerts = 0; const QDateTime currentTime = QDateTime::currentDateTime(); - foreach (const QSslCertificate& cert, certList) { + Q_FOREACH (const QSslCertificate& cert, certList) { // Don't log NULL certificates if (cert.isNull()) continue; @@ -201,7 +199,7 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store) // when uiReady() is called. // // Warning: ipcSendCommandLine() is called early in init, -// so don't use "emit message()", but "QMessageBox::"! +// so don't use "Q_EMIT message()", but "QMessageBox::"! // void PaymentServer::ipcParseCommandLine(int argc, char* argv[]) { @@ -269,7 +267,7 @@ void PaymentServer::ipcParseCommandLine(int argc, char* argv[]) bool PaymentServer::ipcSendCommandLine() { bool fResult = false; - foreach (const QString& r, savedPaymentRequests) + Q_FOREACH (const QString& r, savedPaymentRequests) { QLocalSocket* socket = new QLocalSocket(); socket->connectToServer(ipcServerName(), QIODevice::WriteOnly); @@ -326,7 +324,7 @@ PaymentServer::PaymentServer(QObject* parent, bool startLocalServer) : uriServer = new QLocalServer(this); if (!uriServer->listen(name)) { - // constructor is called early in init, so don't use "emit message()" here + // constructor is called early in init, so don't use "Q_EMIT message()" here QMessageBox::critical(0, tr("Payment request error"), tr("Cannot start bitcoin: click-to-pay handler")); } @@ -394,7 +392,7 @@ void PaymentServer::uiReady() initNetManager(); saveURIs = false; - foreach (const QString& s, savedPaymentRequests) + Q_FOREACH (const QString& s, savedPaymentRequests) { handleURIOrFile(s); } @@ -431,7 +429,7 @@ void PaymentServer::handleURIOrFile(const QString& s) else { qWarning() << "PaymentServer::handleURIOrFile: Invalid URL: " << fetchUrl; - emit message(tr("URI handling"), + Q_EMIT message(tr("URI handling"), tr("Payment request fetch URL is invalid: %1").arg(fetchUrl.toString()), CClientUIInterface::ICON_WARNING); } @@ -445,14 +443,14 @@ void PaymentServer::handleURIOrFile(const QString& s) { CBitcoinAddress address(recipient.address.toStdString()); if (!address.IsValid()) { - emit message(tr("URI handling"), tr("Invalid payment address %1").arg(recipient.address), + Q_EMIT message(tr("URI handling"), tr("Invalid payment address %1").arg(recipient.address), CClientUIInterface::MSG_ERROR); } else - emit receivedPaymentRequest(recipient); + Q_EMIT receivedPaymentRequest(recipient); } else - emit message(tr("URI handling"), + Q_EMIT message(tr("URI handling"), tr("URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters."), CClientUIInterface::ICON_WARNING); @@ -466,12 +464,12 @@ void PaymentServer::handleURIOrFile(const QString& s) SendCoinsRecipient recipient; if (!readPaymentRequestFromFile(s, request)) { - emit message(tr("Payment request file handling"), + Q_EMIT message(tr("Payment request file handling"), tr("Payment request file cannot be read! This can be caused by an invalid payment request file."), CClientUIInterface::ICON_WARNING); } else if (processPaymentRequest(request, recipient)) - emit receivedPaymentRequest(recipient); + Q_EMIT receivedPaymentRequest(recipient); return; } @@ -500,7 +498,7 @@ void PaymentServer::handleURIConnection() // // Warning: readPaymentRequestFromFile() is used in ipcSendCommandLine() -// so don't use "emit message()", but "QMessageBox::"! +// so don't use "Q_EMIT message()", but "QMessageBox::"! // bool PaymentServer::readPaymentRequestFromFile(const QString& filename, PaymentRequestPlus& request) { @@ -533,7 +531,7 @@ bool PaymentServer::processPaymentRequest(const PaymentRequestPlus& request, Sen if (request.IsInitialized()) { // Payment request network matches client network? if (!verifyNetwork(request.getDetails())) { - emit message(tr("Payment request rejected"), tr("Payment request network doesn't match client network."), + Q_EMIT message(tr("Payment request rejected"), tr("Payment request network doesn't match client network."), CClientUIInterface::MSG_ERROR); return false; @@ -542,13 +540,13 @@ bool PaymentServer::processPaymentRequest(const PaymentRequestPlus& request, Sen // Make sure any payment requests involved are still valid. // This is re-checked just before sending coins in WalletModel::sendCoins(). if (verifyExpired(request.getDetails())) { - emit message(tr("Payment request rejected"), tr("Payment request expired."), + Q_EMIT message(tr("Payment request rejected"), tr("Payment request expired."), CClientUIInterface::MSG_ERROR); return false; } } else { - emit message(tr("Payment request error"), tr("Payment request is not initialized."), + Q_EMIT message(tr("Payment request error"), tr("Payment request is not initialized."), CClientUIInterface::MSG_ERROR); return false; @@ -562,7 +560,7 @@ bool PaymentServer::processPaymentRequest(const PaymentRequestPlus& request, Sen QList<std::pair<CScript, CAmount> > sendingTos = request.getPayTo(); QStringList addresses; - foreach(const PAIRTYPE(CScript, CAmount)& sendingTo, sendingTos) { + Q_FOREACH(const PAIRTYPE(CScript, CAmount)& sendingTo, sendingTos) { // Extract and check destination addresses CTxDestination dest; if (ExtractDestination(sendingTo.first, dest)) { @@ -573,7 +571,7 @@ bool PaymentServer::processPaymentRequest(const PaymentRequestPlus& request, Sen // Unauthenticated payment requests to custom bitcoin addresses are not supported // (there is no good way to tell the user where they are paying in a way they'd // have a chance of understanding). - emit message(tr("Payment request rejected"), + Q_EMIT message(tr("Payment request rejected"), tr("Unverified payment requests to custom payment scripts are unsupported."), CClientUIInterface::MSG_ERROR); return false; @@ -583,14 +581,14 @@ bool PaymentServer::processPaymentRequest(const PaymentRequestPlus& request, Sen // but CAmount is defined as int64_t. Because of that we need to verify that amounts are in a valid range // and no overflow has happened. if (!verifyAmount(sendingTo.second)) { - emit message(tr("Payment request rejected"), tr("Invalid payment request."), CClientUIInterface::MSG_ERROR); + Q_EMIT message(tr("Payment request rejected"), tr("Invalid payment request."), CClientUIInterface::MSG_ERROR); return false; } // Extract and check amounts CTxOut txOut(sendingTo.second, sendingTo.first); if (txOut.IsDust(::minRelayTxFee)) { - emit message(tr("Payment request error"), tr("Requested payment amount of %1 is too small (considered dust).") + Q_EMIT message(tr("Payment request error"), tr("Requested payment amount of %1 is too small (considered dust).") .arg(BitcoinUnits::formatWithUnit(optionsModel->getDisplayUnit(), sendingTo.second)), CClientUIInterface::MSG_ERROR); @@ -600,7 +598,7 @@ bool PaymentServer::processPaymentRequest(const PaymentRequestPlus& request, Sen recipient.amount += sendingTo.second; // Also verify that the final amount is still in a valid range after adding additional amounts. if (!verifyAmount(recipient.amount)) { - emit message(tr("Payment request rejected"), tr("Invalid payment request."), CClientUIInterface::MSG_ERROR); + Q_EMIT message(tr("Payment request rejected"), tr("Invalid payment request."), CClientUIInterface::MSG_ERROR); return false; } } @@ -647,7 +645,7 @@ void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipien // Create a new refund address, or re-use: QString account = tr("Refund from %1").arg(recipient.authenticatedMerchant); std::string strAccount = account.toStdString(); - set<CTxDestination> refundAddresses = wallet->GetAccountAddresses(strAccount); + std::set<CTxDestination> refundAddresses = wallet->GetAccountAddresses(strAccount); if (!refundAddresses.empty()) { CScript s = GetScriptForDestination(*refundAddresses.begin()); payments::Output* refund_to = payment.add_refund_to(); @@ -694,7 +692,7 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply) .arg(BIP70_MAX_PAYMENTREQUEST_SIZE); qWarning() << QString("PaymentServer::%1:").arg(__func__) << msg; - emit message(tr("Payment request DoS protection"), msg, CClientUIInterface::MSG_ERROR); + Q_EMIT message(tr("Payment request DoS protection"), msg, CClientUIInterface::MSG_ERROR); return; } @@ -704,7 +702,7 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply) .arg(reply->errorString()); qWarning() << "PaymentServer::netRequestFinished: " << msg; - emit message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR); + Q_EMIT message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR); return; } @@ -718,12 +716,12 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply) if (!request.parse(data)) { qWarning() << "PaymentServer::netRequestFinished: Error parsing payment request"; - emit message(tr("Payment request error"), + Q_EMIT message(tr("Payment request error"), tr("Payment request cannot be parsed!"), CClientUIInterface::MSG_ERROR); } else if (processPaymentRequest(request, recipient)) - emit receivedPaymentRequest(recipient); + Q_EMIT receivedPaymentRequest(recipient); return; } @@ -736,11 +734,11 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply) .arg(reply->request().url().toString()); qWarning() << "PaymentServer::netRequestFinished: " << msg; - emit message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR); + Q_EMIT message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR); } else { - emit receivedPaymentACK(GUIUtil::HtmlEscape(paymentACK.memo())); + Q_EMIT receivedPaymentACK(GUIUtil::HtmlEscape(paymentACK.memo())); } } } @@ -750,11 +748,11 @@ void PaymentServer::reportSslErrors(QNetworkReply* reply, const QList<QSslError> Q_UNUSED(reply); QString errString; - foreach (const QSslError& err, errs) { + Q_FOREACH (const QSslError& err, errs) { qWarning() << "PaymentServer::reportSslErrors: " << err; errString += err.errorString() + "\n"; } - emit message(tr("Network request error"), errString, CClientUIInterface::MSG_ERROR); + Q_EMIT message(tr("Network request error"), errString, CClientUIInterface::MSG_ERROR); } void PaymentServer::setOptionsModel(OptionsModel *optionsModel) @@ -765,7 +763,7 @@ void PaymentServer::setOptionsModel(OptionsModel *optionsModel) void PaymentServer::handlePaymentACK(const QString& paymentACKMsg) { // currently we don't futher process or store the paymentACK message - emit message(tr("Payment acknowledged"), paymentACKMsg, CClientUIInterface::ICON_INFORMATION | CClientUIInterface::MODAL); + Q_EMIT message(tr("Payment acknowledged"), paymentACKMsg, CClientUIInterface::ICON_INFORMATION | CClientUIInterface::MODAL); } bool PaymentServer::verifyNetwork(const payments::PaymentDetails& requestDetails) diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h index 32ed27983e..5df0a14cf7 100644 --- a/src/qt/paymentserver.h +++ b/src/qt/paymentserver.h @@ -98,7 +98,7 @@ public: // Verify the payment request amount is valid static bool verifyAmount(const CAmount& requestAmount); -signals: +Q_SIGNALS: // Fired when a valid payment request is received void receivedPaymentRequest(SendCoinsRecipient); @@ -108,7 +108,7 @@ signals: // Fired when a message should be reported to the user void message(const QString &title, const QString &message, unsigned int style); -public slots: +public Q_SLOTS: // Signal this when the main window's UI is ready // to display payment requests to the user void uiReady(); @@ -119,7 +119,7 @@ public slots: // Handle an incoming URI, URI with local file scheme or file void handleURIOrFile(const QString& s); -private slots: +private Q_SLOTS: void handleURIConnection(); void netRequestFinished(QNetworkReply*); void reportSslErrors(QNetworkReply*, const QList<QSslError> &); diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp index f5904a4d8e..85339166b0 100644 --- a/src/qt/peertablemodel.cpp +++ b/src/qt/peertablemodel.cpp @@ -63,7 +63,7 @@ public: #if QT_VERSION >= 0x040700 cachedNodeStats.reserve(vNodes.size()); #endif - foreach (CNode* pnode, vNodes) + Q_FOREACH (CNode* pnode, vNodes) { CNodeCombinedStats stats; stats.nodeStateStats.nMisbehavior = 0; @@ -92,7 +92,7 @@ public: // build index map mapNodeRows.clear(); int row = 0; - foreach (const CNodeCombinedStats& stats, cachedNodeStats) + Q_FOREACH (const CNodeCombinedStats& stats, cachedNodeStats) mapNodeRows.insert(std::pair<NodeId, int>(stats.nodeStats.nodeid, row++)); } @@ -220,9 +220,9 @@ const CNodeCombinedStats *PeerTableModel::getNodeStats(int idx) void PeerTableModel::refresh() { - emit layoutAboutToBeChanged(); + Q_EMIT layoutAboutToBeChanged(); priv->refreshPeers(); - emit layoutChanged(); + Q_EMIT layoutChanged(); } int PeerTableModel::getRowByNodeId(NodeId nodeid) diff --git a/src/qt/peertablemodel.h b/src/qt/peertablemodel.h index bff7bb824e..fcb89b7611 100644 --- a/src/qt/peertablemodel.h +++ b/src/qt/peertablemodel.h @@ -68,7 +68,7 @@ public: void sort(int column, Qt::SortOrder order); /*@}*/ -public slots: +public Q_SLOTS: void refresh(); private: diff --git a/src/qt/qvalidatedlineedit.h b/src/qt/qvalidatedlineedit.h index f63568d27f..8665acda5e 100644 --- a/src/qt/qvalidatedlineedit.h +++ b/src/qt/qvalidatedlineedit.h @@ -27,11 +27,11 @@ private: bool valid; const QValidator *checkValidator; -public slots: +public Q_SLOTS: void setValid(bool valid); void setEnabled(bool enabled); -private slots: +private Q_SLOTS: void markValid(); void checkValidity(); }; diff --git a/src/qt/qvaluecombobox.cpp b/src/qt/qvaluecombobox.cpp index f73268c958..800436661f 100644 --- a/src/qt/qvaluecombobox.cpp +++ b/src/qt/qvaluecombobox.cpp @@ -27,5 +27,5 @@ void QValueComboBox::setRole(int role) void QValueComboBox::handleSelectionChanged(int idx) { - emit valueChanged(); + Q_EMIT valueChanged(); } diff --git a/src/qt/qvaluecombobox.h b/src/qt/qvaluecombobox.h index dc85d64cb5..5b20e6a5a4 100644 --- a/src/qt/qvaluecombobox.h +++ b/src/qt/qvaluecombobox.h @@ -24,13 +24,13 @@ public: /** Specify model role to use as ordinal value (defaults to Qt::UserRole) */ void setRole(int role); -signals: +Q_SIGNALS: void valueChanged(); private: int role; -private slots: +private Q_SLOTS: void handleSelectionChanged(int idx); }; diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index 28cbd3abed..43b46c63b5 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -185,8 +185,7 @@ void ReceiveCoinsDialog::on_showRequestButton_clicked() return; QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows(); - foreach (QModelIndex index, selection) - { + Q_FOREACH (const QModelIndex& index, selection) { on_recentRequestsView_doubleClicked(index); } } diff --git a/src/qt/receivecoinsdialog.h b/src/qt/receivecoinsdialog.h index 70a1842fa2..6bb159482b 100644 --- a/src/qt/receivecoinsdialog.h +++ b/src/qt/receivecoinsdialog.h @@ -44,7 +44,7 @@ public: void setModel(WalletModel *model); -public slots: +public Q_SLOTS: void clear(); void reject(); void accept(); @@ -60,7 +60,7 @@ private: void copyColumnToClipboard(int column); virtual void resizeEvent(QResizeEvent *event); -private slots: +private Q_SLOTS: void on_receiveButton_clicked(); void on_showRequestButton_clicked(); void on_removeRequestButton_clicked(); diff --git a/src/qt/receiverequestdialog.h b/src/qt/receiverequestdialog.h index 3e5f897be6..69f84ebbd7 100644 --- a/src/qt/receiverequestdialog.h +++ b/src/qt/receiverequestdialog.h @@ -32,7 +32,7 @@ public: explicit QRImageWidget(QWidget *parent = 0); QImage exportImage(); -public slots: +public Q_SLOTS: void saveImage(); void copyImage(); @@ -55,7 +55,7 @@ public: void setModel(OptionsModel *model); void setInfo(const SendCoinsRecipient &info); -private slots: +private Q_SLOTS: void on_btnCopyURI_clicked(); void on_btnCopyAddress_clicked(); diff --git a/src/qt/recentrequeststablemodel.cpp b/src/qt/recentrequeststablemodel.cpp index 543b977d8f..5692a7aaef 100644 --- a/src/qt/recentrequeststablemodel.cpp +++ b/src/qt/recentrequeststablemodel.cpp @@ -119,7 +119,7 @@ QVariant RecentRequestsTableModel::headerData(int section, Qt::Orientation orien void RecentRequestsTableModel::updateAmountColumnTitle() { columns[Amount] = getAmountTitle(); - emit headerDataChanged(Qt::Horizontal,Amount,Amount); + Q_EMIT headerDataChanged(Qt::Horizontal,Amount,Amount); } /** Gets title for amount column including current display unit if optionsModel reference available. */ @@ -214,7 +214,7 @@ void RecentRequestsTableModel::addNewRequest(RecentRequestEntry &recipient) void RecentRequestsTableModel::sort(int column, Qt::SortOrder order) { qSort(list.begin(), list.end(), RecentRequestEntryLessThan(column, order)); - emit dataChanged(index(0, 0, QModelIndex()), index(list.size() - 1, NUMBER_OF_COLUMNS - 1, QModelIndex())); + Q_EMIT dataChanged(index(0, 0, QModelIndex()), index(list.size() - 1, NUMBER_OF_COLUMNS - 1, QModelIndex())); } void RecentRequestsTableModel::updateDisplayUnit() diff --git a/src/qt/recentrequeststablemodel.h b/src/qt/recentrequeststablemodel.h index 85bad126db..64faa72d45 100644 --- a/src/qt/recentrequeststablemodel.h +++ b/src/qt/recentrequeststablemodel.h @@ -89,7 +89,7 @@ public: void addNewRequest(const std::string &recipient); void addNewRequest(RecentRequestEntry &recipient); -public slots: +public Q_SLOTS: void sort(int column, Qt::SortOrder order = Qt::AscendingOrder); void updateDisplayUnit(); diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index f828ce2534..2fafb83d43 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -60,10 +60,10 @@ class RPCExecutor : public QObject { Q_OBJECT -public slots: +public Q_SLOTS: void request(const QString &command); -signals: +Q_SIGNALS: void reply(int category, const QString &command); }; @@ -95,7 +95,7 @@ bool parseCommandLine(std::vector<std::string> &args, const std::string &strComm STATE_ESCAPE_DOUBLEQUOTED } state = STATE_EATING_SPACES; std::string curarg; - foreach(char ch, strCommand) + Q_FOREACH(char ch, strCommand) { switch(state) { @@ -158,7 +158,7 @@ void RPCExecutor::request(const QString &command) std::vector<std::string> args; if(!parseCommandLine(args, command.toStdString())) { - emit reply(RPCConsole::CMD_ERROR, QString("Parse error: unbalanced ' or \"")); + Q_EMIT reply(RPCConsole::CMD_ERROR, QString("Parse error: unbalanced ' or \"")); return; } if(args.empty()) @@ -180,7 +180,7 @@ void RPCExecutor::request(const QString &command) else strPrint = result.write(2); - emit reply(RPCConsole::CMD_REPLY, QString::fromStdString(strPrint)); + Q_EMIT reply(RPCConsole::CMD_REPLY, QString::fromStdString(strPrint)); } catch (UniValue& objError) { @@ -188,16 +188,16 @@ void RPCExecutor::request(const QString &command) { int code = find_value(objError, "code").get_int(); std::string message = find_value(objError, "message").get_str(); - emit reply(RPCConsole::CMD_ERROR, QString::fromStdString(message) + " (code " + QString::number(code) + ")"); + Q_EMIT reply(RPCConsole::CMD_ERROR, QString::fromStdString(message) + " (code " + QString::number(code) + ")"); } catch (const std::runtime_error&) // raised when converting to invalid type, i.e. missing code or message { // Show raw JSON object - emit reply(RPCConsole::CMD_ERROR, QString::fromStdString(objError.write())); + Q_EMIT reply(RPCConsole::CMD_ERROR, QString::fromStdString(objError.write())); } } catch (const std::exception& e) { - emit reply(RPCConsole::CMD_ERROR, QString("Error: ") + QString::fromStdString(e.what())); + Q_EMIT reply(RPCConsole::CMD_ERROR, QString("Error: ") + QString::fromStdString(e.what())); } } @@ -245,7 +245,7 @@ RPCConsole::RPCConsole(QWidget *parent) : RPCConsole::~RPCConsole() { GUIUtil::saveWindowGeometry("nRPCConsoleWindow", this); - emit stopExecutor(); + Q_EMIT stopExecutor(); delete ui; } @@ -431,7 +431,7 @@ void RPCConsole::on_lineEdit_returnPressed() if(!cmd.isEmpty()) { message(CMD_REQUEST, cmd); - emit cmdRequest(cmd); + Q_EMIT cmdRequest(cmd); // Remove command, if already in history history.removeOne(cmd); // Append command to history diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index a309df7ba7..6f42aa08b7 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -46,7 +46,7 @@ protected: virtual bool eventFilter(QObject* obj, QEvent *event); void keyPressEvent(QKeyEvent *); -private slots: +private Q_SLOTS: void on_lineEdit_returnPressed(); void on_tabWidget_currentChanged(int index); /** open the debug.log from the current datadir */ @@ -61,7 +61,7 @@ private slots: /** Show custom context menu on Peers tab */ void showMenu(const QPoint& point); -public slots: +public Q_SLOTS: void clear(); void message(int category, const QString &message, bool html = false); /** Set number of connections shown in the UI */ @@ -79,7 +79,7 @@ public slots: /** Disconnect a selected node on the Peers tab */ void disconnectSelectedNode(); -signals: +Q_SIGNALS: // For RPC command executor void stopExecutor(); void cmdRequest(const QString &command); diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 3d57711568..e13cd714a6 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -251,7 +251,7 @@ void SendCoinsDialog::on_sendButton_clicked() // Format confirmation message QStringList formatted; - foreach(const SendCoinsRecipient &rcp, currentTransaction.getRecipients()) + Q_FOREACH(const SendCoinsRecipient &rcp, currentTransaction.getRecipients()) { // generate bold amount string QString amount = "<b>" + BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), rcp.amount); @@ -305,7 +305,7 @@ void SendCoinsDialog::on_sendButton_clicked() questionString.append("<hr />"); CAmount totalAmount = currentTransaction.getTotalTransactionAmount() + txFee; QStringList alternativeUnits; - foreach(BitcoinUnits::Unit u, BitcoinUnits::availableUnits()) + Q_FOREACH(BitcoinUnits::Unit u, BitcoinUnits::availableUnits()) { if(u != model->getOptionsModel()->getDisplayUnit()) alternativeUnits.append(BitcoinUnits::formatHtmlWithUnit(u, totalAmount)); @@ -540,7 +540,7 @@ void SendCoinsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn return; } - emit message(tr("Send Coins"), msgParams.first, msgParams.second); + Q_EMIT message(tr("Send Coins"), msgParams.first, msgParams.second); } void SendCoinsDialog::minimizeFeeSection(bool fMinimize) diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h index fc513bf2ba..c833da84b2 100644 --- a/src/qt/sendcoinsdialog.h +++ b/src/qt/sendcoinsdialog.h @@ -45,7 +45,7 @@ public: void pasteEntry(const SendCoinsRecipient &rv); bool handlePaymentRequest(const SendCoinsRecipient &recipient); -public slots: +public Q_SLOTS: void clear(); void reject(); void accept(); @@ -62,13 +62,13 @@ private: bool fFeeMinimized; // Process WalletModel::SendCoinsReturn and generate a pair consisting - // of a message and message flags for use in emit message(). + // of a message and message flags for use in Q_EMIT message(). // Additional parameter msgArg can be used via .arg(msgArg). void processSendCoinsReturn(const WalletModel::SendCoinsReturn &sendCoinsReturn, const QString &msgArg = QString()); void minimizeFeeSection(bool fMinimize); void updateFeeMinimizedLabel(); -private slots: +private Q_SLOTS: void on_sendButton_clicked(); void on_buttonChooseFee_clicked(); void on_buttonMinimizeFee_clicked(); @@ -93,7 +93,7 @@ private slots: void updateSmartFeeLabel(); void updateGlobalFeeVariables(); -signals: +Q_SIGNALS: // Fired when a message should be reported to the user void message(const QString &title, const QString &message, unsigned int style); }; diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index 6eec33ffd4..90a8cbdc4e 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -114,7 +114,7 @@ void SendCoinsEntry::clear() void SendCoinsEntry::deleteClicked() { - emit removeEntry(this); + Q_EMIT removeEntry(this); } bool SendCoinsEntry::validate() diff --git a/src/qt/sendcoinsentry.h b/src/qt/sendcoinsentry.h index c2d1185bdd..d7e655fdc3 100644 --- a/src/qt/sendcoinsentry.h +++ b/src/qt/sendcoinsentry.h @@ -45,15 +45,15 @@ public: void setFocus(); -public slots: +public Q_SLOTS: void clear(); -signals: +Q_SIGNALS: void removeEntry(SendCoinsEntry *entry); void payAmountChanged(); void subtractFeeFromAmountChanged(); -private slots: +private Q_SLOTS: void deleteClicked(); void on_payTo_textChanged(const QString &address); void on_addressBookButton_clicked(); diff --git a/src/qt/signverifymessagedialog.h b/src/qt/signverifymessagedialog.h index 27807adc84..bf841e4f8b 100644 --- a/src/qt/signverifymessagedialog.h +++ b/src/qt/signverifymessagedialog.h @@ -35,7 +35,7 @@ private: Ui::SignVerifyMessageDialog *ui; WalletModel *model; -private slots: +private Q_SLOTS: /* sign message */ void on_addressBookButton_SM_clicked(); void on_pasteButton_SM_clicked(); diff --git a/src/qt/splashscreen.h b/src/qt/splashscreen.h index 84e4556dd8..29d16d4eae 100644 --- a/src/qt/splashscreen.h +++ b/src/qt/splashscreen.h @@ -27,7 +27,7 @@ protected: void paintEvent(QPaintEvent *event); void closeEvent(QCloseEvent *event); -public slots: +public Q_SLOTS: /** Slot to call finish() method as it's not defined as slot */ void slotFinish(QWidget *mainWin); diff --git a/src/qt/test/paymentservertests.cpp b/src/qt/test/paymentservertests.cpp index e2ec439b2e..b28934cd31 100644 --- a/src/qt/test/paymentservertests.cpp +++ b/src/qt/test/paymentservertests.cpp @@ -195,7 +195,7 @@ void PaymentServerTests::paymentServerTests() QVERIFY(r.paymentRequest.IsInitialized()); // Extract address and amount from the request QList<std::pair<CScript, CAmount> > sendingTos = r.paymentRequest.getPayTo(); - foreach (const PAIRTYPE(CScript, CAmount)& sendingTo, sendingTos) { + Q_FOREACH (const PAIRTYPE(CScript, CAmount)& sendingTo, sendingTos) { CTxDestination dest; if (ExtractDestination(sendingTo.first, dest)) QCOMPARE(PaymentServer::verifyAmount(sendingTo.second), false); diff --git a/src/qt/test/paymentservertests.h b/src/qt/test/paymentservertests.h index c98bbf0833..71d61fcbe7 100644 --- a/src/qt/test/paymentservertests.h +++ b/src/qt/test/paymentservertests.h @@ -14,7 +14,7 @@ class PaymentServerTests : public QObject { Q_OBJECT -private slots: +private Q_SLOTS: void paymentServerTests(); }; @@ -25,7 +25,7 @@ class RecipientCatcher : public QObject { Q_OBJECT -public slots: +public Q_SLOTS: void getRecipient(SendCoinsRecipient r); public: diff --git a/src/qt/test/uritests.h b/src/qt/test/uritests.h index a0b7dc6c72..434169dcde 100644 --- a/src/qt/test/uritests.h +++ b/src/qt/test/uritests.h @@ -12,7 +12,7 @@ class URITests : public QObject { Q_OBJECT -private slots: +private Q_SLOTS: void uriTests(); }; diff --git a/src/qt/trafficgraphwidget.cpp b/src/qt/trafficgraphwidget.cpp index 0b2eb9eaf2..9b67445bc0 100644 --- a/src/qt/trafficgraphwidget.cpp +++ b/src/qt/trafficgraphwidget.cpp @@ -139,10 +139,10 @@ void TrafficGraphWidget::updateRates() } float tmax = 0.0f; - foreach(float f, vSamplesIn) { + Q_FOREACH(float f, vSamplesIn) { if(f > tmax) tmax = f; } - foreach(float f, vSamplesOut) { + Q_FOREACH(float f, vSamplesOut) { if(f > tmax) tmax = f; } fMax = tmax; diff --git a/src/qt/trafficgraphwidget.h b/src/qt/trafficgraphwidget.h index 4c6b17fe7e..6336a8d144 100644 --- a/src/qt/trafficgraphwidget.h +++ b/src/qt/trafficgraphwidget.h @@ -27,7 +27,7 @@ public: protected: void paintEvent(QPaintEvent *); -public slots: +public Q_SLOTS: void updateRates(); void setGraphRangeMins(int mins); void clear(); diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 5662b16657..af78a51d0f 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -21,8 +21,6 @@ #include <stdint.h> #include <string> -using namespace std; - QString TransactionDesc::FormatTxStatus(const CWalletTx& wtx) { AssertLockHeld(cs_main); @@ -243,14 +241,14 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco strHTML += "<b>" + tr("Transaction ID") + ":</b> " + TransactionRecord::formatSubTxId(wtx.GetHash(), rec->idx) + "<br>"; // Message from normal bitcoin:URI (bitcoin:123...?message=example) - foreach (const PAIRTYPE(string, string)& r, wtx.vOrderForm) + Q_FOREACH (const PAIRTYPE(std::string, std::string)& r, wtx.vOrderForm) if (r.first == "Message") strHTML += "<br><b>" + tr("Message") + ":</b><br>" + GUIUtil::HtmlEscape(r.second, true) + "<br>"; // // PaymentRequest info: // - foreach (const PAIRTYPE(string, string)& r, wtx.vOrderForm) + Q_FOREACH (const PAIRTYPE(std::string, std::string)& r, wtx.vOrderForm) { if (r.first == "PaymentRequest") { diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 34464b4075..e3d64387f7 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -142,7 +142,7 @@ public: { parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex+toInsert.size()-1); int insert_idx = lowerIndex; - foreach(const TransactionRecord &rec, toInsert) + Q_FOREACH(const TransactionRecord &rec, toInsert) { cachedWallet.insert(insert_idx, rec); insert_idx += 1; @@ -245,7 +245,7 @@ TransactionTableModel::~TransactionTableModel() void TransactionTableModel::updateAmountColumnTitle() { columns[Amount] = BitcoinUnits::getAmountColumnTitle(walletModel->getOptionsModel()->getDisplayUnit()); - emit headerDataChanged(Qt::Horizontal,Amount,Amount); + Q_EMIT headerDataChanged(Qt::Horizontal,Amount,Amount); } void TransactionTableModel::updateTransaction(const QString &hash, int status, bool showTransaction) @@ -262,8 +262,8 @@ void TransactionTableModel::updateConfirmations() // Invalidate status (number of confirmations) and (possibly) description // for all rows. Qt is smart enough to only actually request the data for the // visible rows. - emit dataChanged(index(0, Status), index(priv->size()-1, Status)); - emit dataChanged(index(0, ToAddress), index(priv->size()-1, ToAddress)); + Q_EMIT dataChanged(index(0, Status), index(priv->size()-1, Status)); + Q_EMIT dataChanged(index(0, ToAddress), index(priv->size()-1, ToAddress)); } int TransactionTableModel::rowCount(const QModelIndex &parent) const @@ -650,7 +650,7 @@ void TransactionTableModel::updateDisplayUnit() { // emit dataChanged to update Amount column with the current unit updateAmountColumnTitle(); - emit dataChanged(index(0, Amount), index(priv->size()-1, Amount)); + Q_EMIT dataChanged(index(0, Amount), index(priv->size()-1, Amount)); } // queue notifications to show a non freezing progress dialog e.g. for rescan diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h index 30a15df9e6..25c82c764b 100644 --- a/src/qt/transactiontablemodel.h +++ b/src/qt/transactiontablemodel.h @@ -98,7 +98,7 @@ private: QVariant txWatchonlyDecoration(const TransactionRecord *wtx) const; QVariant txAddressDecoration(const TransactionRecord *wtx) const; -public slots: +public Q_SLOTS: /* New transaction, or transaction changed status */ void updateTransaction(const QString &hash, int status, bool showTransaction); void updateConfirmations(); diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 526940632e..998789b3ae 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -341,11 +341,11 @@ void TransactionView::exportClicked() writer.addColumn(tr("ID"), 0, TransactionTableModel::TxIDRole); if(!writer.write()) { - emit message(tr("Exporting Failed"), tr("There was an error trying to save the transaction history to %1.").arg(filename), + Q_EMIT message(tr("Exporting Failed"), tr("There was an error trying to save the transaction history to %1.").arg(filename), CClientUIInterface::MSG_ERROR); } else { - emit message(tr("Exporting Successful"), tr("The transaction history was successfully saved to %1.").arg(filename), + Q_EMIT message(tr("Exporting Successful"), tr("The transaction history was successfully saved to %1.").arg(filename), CClientUIInterface::MSG_INFORMATION); } } diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h index 092d919042..6c35362be4 100644 --- a/src/qt/transactionview.h +++ b/src/qt/transactionview.h @@ -83,7 +83,7 @@ private: bool eventFilter(QObject *obj, QEvent *event); -private slots: +private Q_SLOTS: void contextualMenu(const QPoint &); void dateRangeChanged(); void showDetails(); @@ -95,13 +95,13 @@ private slots: void openThirdPartyTxUrl(QString url); void updateWatchOnlyColumn(bool fHaveWatchOnly); -signals: +Q_SIGNALS: void doubleClicked(const QModelIndex&); /** Fired when a message should be reported to the user */ void message(const QString &title, const QString &message, unsigned int style); -public slots: +public Q_SLOTS: void chooseDate(int idx); void chooseType(int idx); void chooseWatchonly(int idx); diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index 386cf31d73..5e26f3e01b 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -84,7 +84,7 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) : QTextCharFormat bold; bold.setFontWeight(QFont::Bold); - foreach (const QString &line, coreOptions.split("\n")) { + Q_FOREACH (const QString &line, coreOptions.split("\n")) { if (line.startsWith(" -")) { cursor.currentTable()->appendRows(1); diff --git a/src/qt/utilitydialog.h b/src/qt/utilitydialog.h index 288b985f13..47282ae2d0 100644 --- a/src/qt/utilitydialog.h +++ b/src/qt/utilitydialog.h @@ -31,7 +31,7 @@ private: Ui::HelpMessageDialog *ui; QString text; -private slots: +private Q_SLOTS: void on_okButton_accepted(); }; diff --git a/src/qt/walletframe.h b/src/qt/walletframe.h index eea97defc9..5a5e2ab944 100644 --- a/src/qt/walletframe.h +++ b/src/qt/walletframe.h @@ -47,7 +47,7 @@ private: WalletView *currentWalletView(); -public slots: +public Q_SLOTS: /** Switch to overview (home) page */ void gotoOverviewPage(); /** Switch to history (transactions) page */ diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 9b8be76beb..168a0255ff 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -25,8 +25,6 @@ #include <QSet> #include <QTimer> -using namespace std; - WalletModel::WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent) : QObject(parent), wallet(wallet), optionsModel(optionsModel), addressTableModel(0), transactionTableModel(0), @@ -107,7 +105,7 @@ void WalletModel::updateStatus() EncryptionStatus newEncryptionStatus = getEncryptionStatus(); if(cachedEncryptionStatus != newEncryptionStatus) - emit encryptionStatusChanged(newEncryptionStatus); + Q_EMIT encryptionStatusChanged(newEncryptionStatus); } void WalletModel::pollBalanceChanged() @@ -159,7 +157,7 @@ void WalletModel::checkBalanceChanged() cachedWatchOnlyBalance = newWatchOnlyBalance; cachedWatchUnconfBalance = newWatchUnconfBalance; cachedWatchImmatureBalance = newWatchImmatureBalance; - emit balanceChanged(newBalance, newUnconfirmedBalance, newImmatureBalance, + Q_EMIT balanceChanged(newBalance, newUnconfirmedBalance, newImmatureBalance, newWatchOnlyBalance, newWatchUnconfBalance, newWatchImmatureBalance); } } @@ -180,7 +178,7 @@ void WalletModel::updateAddressBook(const QString &address, const QString &label void WalletModel::updateWatchOnlyFlag(bool fHaveWatchonly) { fHaveWatchOnly = fHaveWatchonly; - emit notifyWatchonlyChanged(fHaveWatchonly); + Q_EMIT notifyWatchonlyChanged(fHaveWatchonly); } bool WalletModel::validateAddress(const QString &address) @@ -205,7 +203,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact int nAddresses = 0; // Pre-check input data for validity - foreach(const SendCoinsRecipient &rcp, recipients) + Q_FOREACH(const SendCoinsRecipient &rcp, recipients) { if (rcp.fSubtractFeeFromAmount) fSubtractFeeFromAmount = true; @@ -285,7 +283,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact { return SendCoinsReturn(AmountWithFeeExceedsBalance); } - emit message(tr("Send Coins"), QString::fromStdString(strFailReason), + Q_EMIT message(tr("Send Coins"), QString::fromStdString(strFailReason), CClientUIInterface::MSG_ERROR); return TransactionCreationFailed; } @@ -306,7 +304,7 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran LOCK2(cs_main, wallet->cs_wallet); CWalletTx *newTx = transaction.getTransaction(); - foreach(const SendCoinsRecipient &rcp, transaction.getRecipients()) + Q_FOREACH(const SendCoinsRecipient &rcp, transaction.getRecipients()) { if (rcp.paymentRequest.IsInitialized()) { @@ -337,7 +335,7 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran // Add addresses / update labels that we've sent to to the address book, // and emit coinsSent signal for each recipient - foreach(const SendCoinsRecipient &rcp, transaction.getRecipients()) + Q_FOREACH(const SendCoinsRecipient &rcp, transaction.getRecipients()) { // Don't touch the address book when we have a payment request if (!rcp.paymentRequest.IsInitialized()) @@ -361,7 +359,7 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran } } } - emit coinsSent(wallet, rcp, transaction_array); + Q_EMIT coinsSent(wallet, rcp, transaction_array); } checkBalanceChanged(); // update balance immediately, otherwise there could be a short noticeable delay until pollBalanceChanged hits @@ -521,7 +519,7 @@ WalletModel::UnlockContext WalletModel::requestUnlock() if(was_locked) { // Request UI to unlock wallet - emit requireUnlock(); + Q_EMIT requireUnlock(); } // If wallet is still locked, unlock was failed or cancelled, mark context as invalid bool valid = getEncryptionStatus() != Locked; diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index e263438880..40bc623543 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -227,7 +227,7 @@ private: void unsubscribeFromCoreSignals(); void checkBalanceChanged(); -signals: +Q_SIGNALS: // Signal that balance in wallet changed void balanceChanged(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance, const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance); @@ -252,7 +252,7 @@ signals: // Watch-only address added void notifyWatchonlyChanged(bool fHaveWatchonly); -public slots: +public Q_SLOTS: /* Wallet status might have changed */ void updateStatus(); /* New transaction, or transaction changed status */ diff --git a/src/qt/walletmodeltransaction.cpp b/src/qt/walletmodeltransaction.cpp index 206bb7c774..6a9b2d5bd3 100644 --- a/src/qt/walletmodeltransaction.cpp +++ b/src/qt/walletmodeltransaction.cpp @@ -81,7 +81,7 @@ void WalletModelTransaction::reassignAmounts(int nChangePosRet) CAmount WalletModelTransaction::getTotalTransactionAmount() { CAmount totalTransactionAmount = 0; - foreach(const SendCoinsRecipient &rcp, recipients) + Q_FOREACH(const SendCoinsRecipient &rcp, recipients) { totalTransactionAmount += rcp.amount; } diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index 956c8b8913..c5f556b444 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -153,7 +153,7 @@ void WalletView::processNewTransaction(const QModelIndex& parent, int start, int QString address = ttm->data(index, TransactionTableModel::AddressRole).toString(); QString label = ttm->data(index, TransactionTableModel::LabelRole).toString(); - emit incomingTransaction(date, walletModel->getOptionsModel()->getDisplayUnit(), amount, type, address, label); + Q_EMIT incomingTransaction(date, walletModel->getOptionsModel()->getDisplayUnit(), amount, type, address, label); } void WalletView::gotoOverviewPage() @@ -215,7 +215,7 @@ void WalletView::showOutOfSyncWarning(bool fShow) void WalletView::updateEncryptionStatus() { - emit encryptionStatusChanged(walletModel->getEncryptionStatus()); + Q_EMIT encryptionStatusChanged(walletModel->getEncryptionStatus()); } void WalletView::encryptWallet(bool status) @@ -239,11 +239,11 @@ void WalletView::backupWallet() return; if (!walletModel->backupWallet(filename)) { - emit message(tr("Backup Failed"), tr("There was an error trying to save the wallet data to %1.").arg(filename), + Q_EMIT message(tr("Backup Failed"), tr("There was an error trying to save the wallet data to %1.").arg(filename), CClientUIInterface::MSG_ERROR); } else { - emit message(tr("Backup Successful"), tr("The wallet data was successfully saved to %1.").arg(filename), + Q_EMIT message(tr("Backup Successful"), tr("The wallet data was successfully saved to %1.").arg(filename), CClientUIInterface::MSG_INFORMATION); } } diff --git a/src/qt/walletview.h b/src/qt/walletview.h index 1840e21e9c..87c5d7bfbf 100644 --- a/src/qt/walletview.h +++ b/src/qt/walletview.h @@ -65,7 +65,7 @@ private: QProgressDialog *progressDialog; -public slots: +public Q_SLOTS: /** Switch to overview (home) page */ void gotoOverviewPage(); /** Switch to history (transactions) page */ @@ -105,7 +105,7 @@ public slots: /** Show progress dialog e.g. for rescan */ void showProgress(const QString &title, int nProgress); -signals: +Q_SIGNALS: /** Signal that we want to show the main window */ void showNormalIfMinimized(); /** Fired when a message should be reported to the user */ diff --git a/src/rest.cpp b/src/rest.cpp index a1bd893bec..dfe01495f7 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -65,6 +65,7 @@ public: extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); extern UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); extern void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); +extern UniValue blockheaderToJSON(const CBlockIndex* blockindex); static RestErr RESTERR(enum HTTPStatusCode status, string message) { @@ -134,14 +135,14 @@ static bool rest_headers(AcceptedConnection* conn, if (!ParseHashStr(hashStr, hash)) throw RESTERR(HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); - std::vector<CBlockHeader> headers; + std::vector<const CBlockIndex *> headers; headers.reserve(count); { LOCK(cs_main); BlockMap::const_iterator it = mapBlockIndex.find(hash); const CBlockIndex *pindex = (it != mapBlockIndex.end()) ? it->second : NULL; while (pindex != NULL && chainActive.Contains(pindex)) { - headers.push_back(pindex->GetBlockHeader()); + headers.push_back(pindex); if (headers.size() == (unsigned long)count) break; pindex = chainActive.Next(pindex); @@ -149,8 +150,8 @@ static bool rest_headers(AcceptedConnection* conn, } CDataStream ssHeader(SER_NETWORK, PROTOCOL_VERSION); - BOOST_FOREACH(const CBlockHeader &header, headers) { - ssHeader << header; + BOOST_FOREACH(const CBlockIndex *pindex, headers) { + ssHeader << pindex->GetBlockHeader(); } switch (rf) { @@ -166,6 +167,16 @@ static bool rest_headers(AcceptedConnection* conn, return true; } + case RF_JSON: { + UniValue jsonHeaders(UniValue::VARR); + BOOST_FOREACH(const CBlockIndex *pindex, headers) { + jsonHeaders.push_back(blockheaderToJSON(pindex)); + } + string strJSON = jsonHeaders.write() + "\n"; + conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; + return true; + } + default: { throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: .bin, .hex)"); } diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index b7c3eb1724..f1c5ffe050 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -77,7 +77,6 @@ UniValue blockheaderToJSON(const CBlockIndex* blockindex) return result; } - UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false) { UniValue result(UniValue::VOBJ); @@ -118,7 +117,6 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx return result; } - UniValue getblockcount(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) @@ -596,6 +594,8 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) " \"difficulty\": xxxxxx, (numeric) the current difficulty\n" " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n" " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n" + " \"pruned\": xx, (boolean) if the blocks are subject to pruning\n" + " \"pruneheight\": xxxxxx, (numeric) heighest block available\n" " \"softforks\": [ (array) status of softforks in progress\n" " {\n" " \"id\": \"xxxx\", (string) name of softfork\n" @@ -760,6 +760,7 @@ UniValue getmempoolinfo(const UniValue& params, bool fHelp) "{\n" " \"size\": xxxxx (numeric) Current tx count\n" " \"bytes\": xxxxx (numeric) Sum of all tx sizes\n" + " \"usage\": xxxxx (numeric) Total memory usage for the mempool\n" "}\n" "\nExamples:\n" + HelpExampleCli("getmempoolinfo", "") @@ -769,6 +770,7 @@ UniValue getmempoolinfo(const UniValue& params, bool fHelp) UniValue ret(UniValue::VOBJ); ret.push_back(Pair("size", (int64_t) mempool.size())); ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize())); + ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage())); return ret; } diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 9c6fb10af0..703b0ee653 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -666,16 +666,15 @@ UniValue estimatefee(const UniValue& params, bool fHelp) if (fHelp || params.size() != 1) throw runtime_error( "estimatefee nblocks\n" - "\nEstimates the approximate fee per kilobyte\n" - "needed for a transaction to begin confirmation\n" - "within nblocks blocks.\n" + "\nEstimates the approximate fee per kilobyte needed for a transaction to begin\n" + "confirmation within nblocks blocks.\n" "\nArguments:\n" "1. nblocks (numeric)\n" "\nResult:\n" - "n : (numeric) estimated fee-per-kilobyte\n" + "n (numeric) estimated fee-per-kilobyte\n" "\n" - "-1.0 is returned if not enough transactions and\n" - "blocks have been observed to make an estimate.\n" + "A negative value is returned if not enough transactions and blocks\n" + "have been observed to make an estimate.\n" "\nExample:\n" + HelpExampleCli("estimatefee", "6") ); @@ -698,16 +697,15 @@ UniValue estimatepriority(const UniValue& params, bool fHelp) if (fHelp || params.size() != 1) throw runtime_error( "estimatepriority nblocks\n" - "\nEstimates the approximate priority\n" - "a zero-fee transaction needs to begin confirmation\n" - "within nblocks blocks.\n" + "\nEstimates the approximate priority a zero-fee transaction needs to begin\n" + "confirmation within nblocks blocks.\n" "\nArguments:\n" "1. nblocks (numeric)\n" "\nResult:\n" - "n : (numeric) estimated priority\n" + "n (numeric) estimated priority\n" "\n" - "-1.0 is returned if not enough transactions and\n" - "blocks have been observed to make an estimate.\n" + "A negative value is returned if not enough transactions and blocks\n" + "have been observed to make an estimate.\n" "\nExample:\n" + HelpExampleCli("estimatepriority", "6") ); diff --git a/src/rpcprotocol.cpp b/src/rpcprotocol.cpp index 89dec2977e..2e5c913734 100644 --- a/src/rpcprotocol.cpp +++ b/src/rpcprotocol.cpp @@ -6,6 +6,7 @@ #include "rpcprotocol.h" #include "clientversion.h" +#include "random.h" #include "tinyformat.h" #include "util.h" #include "utilstrencodings.h" @@ -13,6 +14,7 @@ #include "version.h" #include <stdint.h> +#include <fstream> #include <boost/algorithm/string.hpp> #include <boost/asio.hpp> @@ -287,3 +289,68 @@ UniValue JSONRPCError(int code, const string& message) error.push_back(Pair("message", message)); return error; } + +/** Username used when cookie authentication is in use (arbitrary, only for + * recognizability in debugging/logging purposes) + */ +static const std::string COOKIEAUTH_USER = "__cookie__"; +/** Default name for auth cookie file */ +static const std::string COOKIEAUTH_FILE = ".cookie"; + +boost::filesystem::path GetAuthCookieFile() +{ + boost::filesystem::path path(GetArg("-rpccookiefile", COOKIEAUTH_FILE)); + if (!path.is_complete()) path = GetDataDir() / path; + return path; +} + +bool GenerateAuthCookie(std::string *cookie_out) +{ + unsigned char rand_pwd[32]; + GetRandBytes(rand_pwd, 32); + std::string cookie = COOKIEAUTH_USER + ":" + EncodeBase64(&rand_pwd[0],32); + + /** the umask determines what permissions are used to create this file - + * these are set to 077 in init.cpp unless overridden with -sysperms. + */ + std::ofstream file; + boost::filesystem::path filepath = GetAuthCookieFile(); + file.open(filepath.string().c_str()); + if (!file.is_open()) { + LogPrintf("Unable to open cookie authentication file %s for writing\n", filepath.string()); + return false; + } + file << cookie; + file.close(); + LogPrintf("Generated RPC authentication cookie %s\n", filepath.string()); + + if (cookie_out) + *cookie_out = cookie; + return true; +} + +bool GetAuthCookie(std::string *cookie_out) +{ + std::ifstream file; + std::string cookie; + boost::filesystem::path filepath = GetAuthCookieFile(); + file.open(filepath.string().c_str()); + if (!file.is_open()) + return false; + std::getline(file, cookie); + file.close(); + + if (cookie_out) + *cookie_out = cookie; + return true; +} + +void DeleteAuthCookie() +{ + try { + boost::filesystem::remove(GetAuthCookieFile()); + } catch (const boost::filesystem::filesystem_error& e) { + LogPrintf("%s: Unable to remove random auth cookie file: %s\n", __func__, e.what()); + } +} + diff --git a/src/rpcprotocol.h b/src/rpcprotocol.h index ccd2439c9f..2360ec2c60 100644 --- a/src/rpcprotocol.h +++ b/src/rpcprotocol.h @@ -14,6 +14,7 @@ #include <boost/iostreams/stream.hpp> #include <boost/asio.hpp> #include <boost/asio/ssl.hpp> +#include <boost/filesystem.hpp> #include "univalue/univalue.h" @@ -165,4 +166,13 @@ UniValue JSONRPCReplyObj(const UniValue& result, const UniValue& error, const Un std::string JSONRPCReply(const UniValue& result, const UniValue& error, const UniValue& id); UniValue JSONRPCError(int code, const std::string& message); +/** Get name of RPC authentication cookie file */ +boost::filesystem::path GetAuthCookieFile(); +/** Generate a new RPC authentication cookie and write it to disk */ +bool GenerateAuthCookie(std::string *cookie_out); +/** Read the RPC authentication cookie from disk */ +bool GetAuthCookie(std::string *cookie_out); +/** Delete RPC authentication cookie from disk */ +void DeleteAuthCookie(); + #endif // BITCOIN_RPCPROTOCOL_H diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 287cfb2f13..bcad06a0c1 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -124,7 +124,7 @@ CAmount AmountFromValue(const UniValue& value) if (!value.isReal() && !value.isNum()) throw JSONRPCError(RPC_TYPE_ERROR, "Amount is not a number"); CAmount amount; - if (!ParseMoney(value.getValStr(), amount)) + if (!ParseFixedPoint(value.getValStr(), 8, &amount)) throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount"); if (!MoneyRange(amount)) throw JSONRPCError(RPC_TYPE_ERROR, "Amount out of range"); @@ -597,28 +597,18 @@ void StartRPCThreads() strAllowed += subnet.ToString() + " "; LogPrint("rpc", "Allowing RPC connections from: %s\n", strAllowed); - strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; - if (((mapArgs["-rpcpassword"] == "") || - (mapArgs["-rpcuser"] == mapArgs["-rpcpassword"])) && Params().RequireRPCPassword()) + if (mapArgs["-rpcpassword"] == "") { - unsigned char rand_pwd[32]; - GetRandBytes(rand_pwd, 32); - uiInterface.ThreadSafeMessageBox(strprintf( - _("To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file:\n" - "%s\n" - "It is recommended you use the following random password:\n" - "rpcuser=bitcoinrpc\n" - "rpcpassword=%s\n" - "(you do not need to remember this password)\n" - "The username and password MUST NOT be the same.\n" - "If the file does not exist, create it with owner-readable-only file permissions.\n" - "It is also recommended to set alertnotify so you are notified of problems;\n" - "for example: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com\n"), - GetConfigFile().string(), - EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32)), - "", CClientUIInterface::MSG_ERROR | CClientUIInterface::SECURE); - StartShutdown(); - return; + LogPrintf("No rpcpassword set - using random cookie authentication\n"); + if (!GenerateAuthCookie(&strRPCUserColonPass)) { + uiInterface.ThreadSafeMessageBox( + _("Error: A fatal internal error occured, see debug.log for details"), // Same message as AbortNode + "", CClientUIInterface::MSG_ERROR); + StartShutdown(); + return; + } + } else { + strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; } assert(rpc_io_service == NULL); @@ -769,6 +759,8 @@ void StopRPCThreads() } deadlineTimers.clear(); + DeleteAuthCookie(); + rpc_io_service->stop(); g_rpcSignals.Stopped(); if (rpc_worker_group != NULL) diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index 34b311b804..13d848311a 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -70,9 +70,9 @@ public: // Manually recompute the dynamic usage of the whole data, and compare it. size_t ret = memusage::DynamicUsage(cacheCoins); for (CCoinsMap::iterator it = cacheCoins.begin(); it != cacheCoins.end(); it++) { - ret += memusage::DynamicUsage(it->second.coins); + ret += it->second.coins.DynamicMemoryUsage(); } - BOOST_CHECK_EQUAL(memusage::DynamicUsage(*this), ret); + BOOST_CHECK_EQUAL(DynamicMemoryUsage(), ret); } }; diff --git a/src/test/data/bitcoin-util-test.json b/src/test/data/bitcoin-util-test.json index 6090421cb6..afd35af503 100644 --- a/src/test/data/bitcoin-util-test.json +++ b/src/test/data/bitcoin-util-test.json @@ -52,7 +52,7 @@ ["-create", "in=4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485:0", "set=privatekeys:[\"5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf\"]", - "set=prevtxs:[{\"txid\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\",\"vout\":0,\"scriptPubKey\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\"}]", + "set=prevtxs:[{\"txid\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\",\"vout\":0,\"scriptPubKey\":\"76a91491b24bf9f5288532960ac687abb035127b1d28a588ac\"}]", "sign=ALL", "outaddr=0.001:193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"], "output_cmp": "txcreatesign.hex" diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json index 9def4042da..20bdbd08a5 100644 --- a/src/test/data/tx_invalid.json +++ b/src/test/data/tx_invalid.json @@ -137,6 +137,8 @@ ["Argument missing"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "NOP2 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000001b1010000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], ["Argument negative with by-blockheight nLockTime=0"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 NOP2 1"]], @@ -145,10 +147,14 @@ ["Argument negative with by-blocktime nLockTime=500,000,000"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 NOP2 1"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000004005194b1010000000100000000000000000002000000", "P2SH,CHECKLOCKTIMEVERIFY"], ["Input locked"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0"]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000000251b1ffffffff0100000000000000000002000000", "P2SH,CHECKLOCKTIMEVERIFY"], ["Another input being unlocked isn't sufficient; the CHECKLOCKTIMEVERIFY-using input must be unlocked"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"] , @@ -158,6 +164,8 @@ ["Argument/tx height/time mismatch, both versions"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0"]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000000251b100000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]], diff --git a/src/test/data/txcreatesign.hex b/src/test/data/txcreatesign.hex index 56ce28a865..a46fcc88cb 100644 --- a/src/test/data/txcreatesign.hex +++ b/src/test/data/txcreatesign.hex @@ -1 +1 @@ -01000000018594c5bdcaec8f06b78b596f31cd292a294fd031e24eec716f43dac91ea7494d0000000000ffffffff01a0860100000000001976a9145834479edbbe0539b31ffd3a8f8ebadc2165ed0188ac00000000 +01000000018594c5bdcaec8f06b78b596f31cd292a294fd031e24eec716f43dac91ea7494d000000008b48304502210096a75056c9e2cc62b7214777b3d2a592cfda7092520126d4ebfcd6d590c99bd8022051bb746359cf98c0603f3004477eac68701132380db8facba19c89dc5ab5c5e201410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ffffffff01a0860100000000001976a9145834479edbbe0539b31ffd3a8f8ebadc2165ed0188ac00000000 diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 9e99ff6286..25599beafc 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -142,6 +142,24 @@ BOOST_AUTO_TEST_CASE(rpc_parse_monetary_values) BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("1.00000000")), 100000000LL); BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("20999999.9999999")), 2099999999999990LL); BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("20999999.99999999")), 2099999999999999LL); + + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("1e-8")), COIN/100000000); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.1e-7")), COIN/100000000); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.01e-6")), COIN/100000000); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.0000000000000000000000000000000000000000000000000000000000000000000000000001e+68")), COIN/100000000); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("10000000000000000000000000000000000000000000000000000000000000000e-64")), COIN); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000e64")), COIN); + + BOOST_CHECK_THROW(AmountFromValue(ValueFromString("1e-9")), UniValue); //should fail + BOOST_CHECK_THROW(AmountFromValue(ValueFromString("0.000000019")), UniValue); //should fail + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.00000001000000")), 1LL); //should pass, cut trailing 0 + BOOST_CHECK_THROW(AmountFromValue(ValueFromString("19e-9")), UniValue); //should fail + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.19e-6")), 19); //should pass, leading 0 is present + + BOOST_CHECK_THROW(AmountFromValue(ValueFromString("92233720368.54775808")), UniValue); //overflow error + BOOST_CHECK_THROW(AmountFromValue(ValueFromString("1e+11")), UniValue); //overflow error + BOOST_CHECK_THROW(AmountFromValue(ValueFromString("1e11")), UniValue); //overflow error signless + BOOST_CHECK_THROW(AmountFromValue(ValueFromString("93e+9")), UniValue); //overflow error } BOOST_AUTO_TEST_CASE(json_parse_errors) @@ -151,6 +169,9 @@ BOOST_AUTO_TEST_CASE(json_parse_errors) // Valid, with leading or trailing whitespace BOOST_CHECK_EQUAL(ParseNonRFCJSONValue(" 1.0").get_real(), 1.0); BOOST_CHECK_EQUAL(ParseNonRFCJSONValue("1.0 ").get_real(), 1.0); + + BOOST_CHECK_THROW(AmountFromValue(ParseNonRFCJSONValue(".19e-6")), std::runtime_error); //should fail, missing leading 0, therefore invalid JSON + BOOST_CHECK_EQUAL(AmountFromValue(ParseNonRFCJSONValue("0.00000000000000000000000000000000000001e+30 ")), 1); // Invalid, initial garbage BOOST_CHECK_THROW(ParseNonRFCJSONValue("[1.0"), std::runtime_error); BOOST_CHECK_THROW(ParseNonRFCJSONValue("a1.0"), std::runtime_error); diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 5cb5894251..e956cc5b90 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -418,4 +418,70 @@ BOOST_AUTO_TEST_CASE(test_FormatSubVersion) BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments),std::string("/Test:0.9.99(comment1)/")); BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments2),std::string("/Test:0.9.99(comment1; comment2)/")); } + +BOOST_AUTO_TEST_CASE(test_ParseFixedPoint) +{ + int64_t amount = 0; + BOOST_CHECK(ParseFixedPoint("0", 8, &amount)); + BOOST_CHECK_EQUAL(amount, 0LL); + BOOST_CHECK(ParseFixedPoint("1", 8, &amount)); + BOOST_CHECK_EQUAL(amount, 100000000LL); + BOOST_CHECK(ParseFixedPoint("0.0", 8, &amount)); + BOOST_CHECK_EQUAL(amount, 0LL); + BOOST_CHECK(ParseFixedPoint("-0.1", 8, &amount)); + BOOST_CHECK_EQUAL(amount, -10000000LL); + BOOST_CHECK(ParseFixedPoint("1.1", 8, &amount)); + BOOST_CHECK_EQUAL(amount, 110000000LL); + BOOST_CHECK(ParseFixedPoint("1.10000000000000000", 8, &amount)); + BOOST_CHECK_EQUAL(amount, 110000000LL); + BOOST_CHECK(ParseFixedPoint("1.1e1", 8, &amount)); + BOOST_CHECK_EQUAL(amount, 1100000000LL); + BOOST_CHECK(ParseFixedPoint("1.1e-1", 8, &amount)); + BOOST_CHECK_EQUAL(amount, 11000000LL); + BOOST_CHECK(ParseFixedPoint("1000", 8, &amount)); + BOOST_CHECK_EQUAL(amount, 100000000000LL); + BOOST_CHECK(ParseFixedPoint("-1000", 8, &amount)); + BOOST_CHECK_EQUAL(amount, -100000000000LL); + BOOST_CHECK(ParseFixedPoint("0.00000001", 8, &amount)); + BOOST_CHECK_EQUAL(amount, 1LL); + BOOST_CHECK(ParseFixedPoint("0.0000000100000000", 8, &amount)); + BOOST_CHECK_EQUAL(amount, 1LL); + BOOST_CHECK(ParseFixedPoint("-0.00000001", 8, &amount)); + BOOST_CHECK_EQUAL(amount, -1LL); + BOOST_CHECK(ParseFixedPoint("1000000000.00000001", 8, &amount)); + BOOST_CHECK_EQUAL(amount, 100000000000000001LL); + BOOST_CHECK(ParseFixedPoint("9999999999.99999999", 8, &amount)); + BOOST_CHECK_EQUAL(amount, 999999999999999999LL); + BOOST_CHECK(ParseFixedPoint("-9999999999.99999999", 8, &amount)); + BOOST_CHECK_EQUAL(amount, -999999999999999999LL); + + BOOST_CHECK(!ParseFixedPoint("", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("-", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("a-1000", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("-a1000", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("-1000a", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("-01000", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("00.1", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint(".1", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("--0.1", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("0.000000001", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("-0.000000001", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("0.00000001000000001", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("-10000000000.00000000", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("10000000000.00000000", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("-10000000000.00000001", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("10000000000.00000001", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("-10000000000.00000009", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("10000000000.00000009", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("-99999999999.99999999", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("99999909999.09999999", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("92233720368.54775807", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("92233720368.54775808", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("-92233720368.54775808", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("-92233720368.54775809", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("1.1e", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("1.1e-", 8, &amount)); + BOOST_CHECK(!ParseFixedPoint("1.", 8, &amount)); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 2292191be4..5bc06e5056 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -18,7 +18,7 @@ using namespace std; CTxMemPoolEntry::CTxMemPoolEntry(): - nFee(0), nTxSize(0), nModSize(0), nTime(0), dPriority(0.0), hadNoDependencies(false) + nFee(0), nTxSize(0), nModSize(0), nUsageSize(0), nTime(0), dPriority(0.0), hadNoDependencies(false) { nHeight = MEMPOOL_HEIGHT; } @@ -31,6 +31,7 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, { nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); nModSize = tx.CalculateModifiedSize(nTxSize); + nUsageSize = RecursiveDynamicUsage(tx); } CTxMemPoolEntry::CTxMemPoolEntry(const CTxMemPoolEntry& other) @@ -101,6 +102,7 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, mapNextTx[tx.vin[i].prevout] = CInPoint(&tx, i); nTransactionsUpdated++; totalTxSize += entry.GetTxSize(); + cachedInnerUsage += entry.DynamicMemoryUsage(); minerPolicyEstimator->processTransaction(entry, fCurrentEstimate); return true; @@ -146,6 +148,7 @@ void CTxMemPool::remove(const CTransaction &origTx, std::list<CTransaction>& rem removed.push_back(tx); totalTxSize -= mapTx[hash].GetTxSize(); + cachedInnerUsage -= mapTx[hash].DynamicMemoryUsage(); mapTx.erase(hash); nTransactionsUpdated++; minerPolicyEstimator->removeTx(hash); @@ -226,6 +229,7 @@ void CTxMemPool::clear() mapTx.clear(); mapNextTx.clear(); totalTxSize = 0; + cachedInnerUsage = 0; ++nTransactionsUpdated; } @@ -237,6 +241,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const LogPrint("mempool", "Checking mempool with %u transactions and %u inputs\n", (unsigned int)mapTx.size(), (unsigned int)mapNextTx.size()); uint64_t checkTotal = 0; + uint64_t innerUsage = 0; CCoinsViewCache mempoolDuplicate(const_cast<CCoinsViewCache*>(pcoins)); @@ -245,6 +250,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const for (std::map<uint256, CTxMemPoolEntry>::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { unsigned int i = 0; checkTotal += it->second.GetTxSize(); + innerUsage += it->second.DynamicMemoryUsage(); const CTransaction& tx = it->second.GetTx(); bool fDependsWait = false; BOOST_FOREACH(const CTxIn &txin, tx.vin) { @@ -299,6 +305,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const } assert(totalTxSize == checkTotal); + assert(innerUsage == cachedInnerUsage); } void CTxMemPool::queryHashes(vector<uint256>& vtxid) @@ -419,3 +426,8 @@ bool CCoinsViewMemPool::GetCoins(const uint256 &txid, CCoins &coins) const { bool CCoinsViewMemPool::HaveCoins(const uint256 &txid) const { return mempool.exists(txid) || base->HaveCoins(txid); } + +size_t CTxMemPool::DynamicMemoryUsage() const { + LOCK(cs); + return memusage::DynamicUsage(mapTx) + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + cachedInnerUsage; +} diff --git a/src/txmempool.h b/src/txmempool.h index 7271a5f603..ea36ce1ad5 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -40,6 +40,7 @@ private: CAmount nFee; //! Cached to avoid expensive parent-transaction lookups size_t nTxSize; //! ... and avoid recomputing tx size size_t nModSize; //! ... and modified size for priority + size_t nUsageSize; //! ... and total memory usage int64_t nTime; //! Local time when entering the mempool double dPriority; //! Priority when entering the mempool unsigned int nHeight; //! Chain height when entering the mempool @@ -58,6 +59,7 @@ public: int64_t GetTime() const { return nTime; } unsigned int GetHeight() const { return nHeight; } bool WasClearAtEntry() const { return hadNoDependencies; } + size_t DynamicMemoryUsage() const { return nUsageSize; } }; class CBlockPolicyEstimator; @@ -73,6 +75,7 @@ public: CInPoint(const CTransaction* ptxIn, uint32_t nIn) { ptx = ptxIn; n = nIn; } void SetNull() { ptx = NULL; n = (uint32_t) -1; } bool IsNull() const { return (ptx == NULL && n == (uint32_t) -1); } + size_t DynamicMemoryUsage() const { return 0; } }; /** @@ -93,6 +96,7 @@ private: CBlockPolicyEstimator* minerPolicyEstimator; uint64_t totalTxSize; //! sum of all mempool tx' byte sizes + uint64_t cachedInnerUsage; //! sum of dynamic memory usage of all the map elements (NOT the maps themselves) public: mutable CCriticalSection cs; @@ -139,6 +143,7 @@ public: LOCK(cs); return mapTx.size(); } + uint64_t GetTotalTxSize() { LOCK(cs); @@ -162,6 +167,8 @@ public: /** Write/Read estimates to disk */ bool WriteFeeEstimates(CAutoFile& fileout) const; bool ReadFeeEstimates(CAutoFile& filein); + + size_t DynamicMemoryUsage() const; }; /** diff --git a/src/util.cpp b/src/util.cpp index 634d8a7056..97fecc6c8e 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -83,6 +83,7 @@ #include <boost/thread.hpp> #include <openssl/crypto.h> #include <openssl/rand.h> +#include <openssl/conf.h> // Work around clang compilation problem in Boost 1.46: // /usr/include/boost/program_options/detail/config_file.hpp:163:17: error: call to function 'to_internal' that is neither visible in the template definition nor found by argument-dependent lookup @@ -134,6 +135,13 @@ public: ppmutexOpenSSL[i] = new CCriticalSection(); CRYPTO_set_locking_callback(locking_callback); + // OpenSSL can optionally load a config file which lists optional loadable modules and engines. + // We don't use them so we don't require the config. However some of our libs may call functions + // which attempt to load the config file, possibly resulting in an exit() or crash if it is missing + // or corrupt. Explicitly tell OpenSSL not to try to load the file. The result for our libs will be + // that the config appears to have been loaded and there are no modules/engines available. + OPENSSL_no_config(); + #ifdef WIN32 // Seed OpenSSL PRNG with current contents of the screen RAND_screen(); diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp index 7d1de7d6a8..7208ca9474 100644 --- a/src/utilstrencodings.cpp +++ b/src/utilstrencodings.cpp @@ -538,3 +538,123 @@ int atoi(const std::string& str) { return atoi(str.c_str()); } + +/** Upper bound for mantissa. + * 10^18-1 is the largest arbitrary decimal that will fit in a signed 64-bit integer. + * Larger integers cannot consist of arbitrary combinations of 0-9: + * + * 999999999999999999 1^18-1 + * 9223372036854775807 (1<<63)-1 (max int64_t) + * 9999999999999999999 1^19-1 (would overflow) + */ +static const int64_t UPPER_BOUND = 1000000000000000000LL - 1LL; + +/** Helper function for ParseFixedPoint */ +static inline bool ProcessMantissaDigit(char ch, int64_t &mantissa, int &mantissa_tzeros) +{ + if(ch == '0') + ++mantissa_tzeros; + else { + for (int i=0; i<=mantissa_tzeros; ++i) { + if (mantissa > (UPPER_BOUND / 10LL)) + return false; /* overflow */ + mantissa *= 10; + } + mantissa += ch - '0'; + mantissa_tzeros = 0; + } + return true; +} + +bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out) +{ + int64_t mantissa = 0; + int64_t exponent = 0; + int mantissa_tzeros = 0; + bool mantissa_sign = false; + bool exponent_sign = false; + int ptr = 0; + int end = val.size(); + int point_ofs = 0; + + if (ptr < end && val[ptr] == '-') { + mantissa_sign = true; + ++ptr; + } + if (ptr < end) + { + if (val[ptr] == '0') { + /* pass single 0 */ + ++ptr; + } else if (val[ptr] >= '1' && val[ptr] <= '9') { + while (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') { + if (!ProcessMantissaDigit(val[ptr], mantissa, mantissa_tzeros)) + return false; /* overflow */ + ++ptr; + } + } else return false; /* missing expected digit */ + } else return false; /* empty string or loose '-' */ + if (ptr < end && val[ptr] == '.') + { + ++ptr; + if (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') + { + while (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') { + if (!ProcessMantissaDigit(val[ptr], mantissa, mantissa_tzeros)) + return false; /* overflow */ + ++ptr; + ++point_ofs; + } + } else return false; /* missing expected digit */ + } + if (ptr < end && (val[ptr] == 'e' || val[ptr] == 'E')) + { + ++ptr; + if (ptr < end && val[ptr] == '+') + ++ptr; + else if (ptr < end && val[ptr] == '-') { + exponent_sign = true; + ++ptr; + } + if (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') { + while (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') { + if (exponent > (UPPER_BOUND / 10LL)) + return false; /* overflow */ + exponent = exponent * 10 + val[ptr] - '0'; + ++ptr; + } + } else return false; /* missing expected digit */ + } + if (ptr != end) + return false; /* trailing garbage */ + + /* finalize exponent */ + if (exponent_sign) + exponent = -exponent; + exponent = exponent - point_ofs + mantissa_tzeros; + + /* finalize mantissa */ + if (mantissa_sign) + mantissa = -mantissa; + + /* convert to one 64-bit fixed-point value */ + exponent += decimals; + if (exponent < 0) + return false; /* cannot represent values smaller than 10^-decimals */ + if (exponent >= 18) + return false; /* cannot represent values larger than or equal to 10^(18-decimals) */ + + for (int i=0; i < exponent; ++i) { + if (mantissa > (UPPER_BOUND / 10LL) || mantissa < -(UPPER_BOUND / 10LL)) + return false; /* overflow */ + mantissa *= 10; + } + if (mantissa > UPPER_BOUND || mantissa < -UPPER_BOUND) + return false; /* overflow */ + + if (amount_out) + *amount_out = mantissa; + + return true; +} + diff --git a/src/utilstrencodings.h b/src/utilstrencodings.h index 58329b51bb..dcd56751f2 100644 --- a/src/utilstrencodings.h +++ b/src/utilstrencodings.h @@ -109,4 +109,11 @@ bool TimingResistantEqual(const T& a, const T& b) return accumulator == 0; } +/** Parse number as fixed point according to JSON number syntax. + * See http://json.org/number.gif + * @returns true on success, false on error. + * @note The result must be in the range (-10^18,10^18), otherwise an overflow error will trigger. + */ +bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out); + #endif // BITCOIN_UTILSTRENCODINGS_H |