aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml1
-rw-r--r--configure.ac13
-rw-r--r--src/Makefile.am2
-rw-r--r--src/Makefile.test.include2
-rw-r--r--src/arith_uint256.cpp9
-rw-r--r--src/bitcoin-cli.cpp30
-rw-r--r--src/bitcoin-tx.cpp50
-rw-r--r--src/chainparams.cpp46
-rw-r--r--src/chainparams.h31
-rw-r--r--src/chainparamsbase.cpp3
-rw-r--r--src/chainparamsbase.h1
-rw-r--r--src/compat/byteswap.h47
-rw-r--r--src/compat/endian.h194
-rw-r--r--src/crypto/common.h76
-rw-r--r--src/db.cpp77
-rw-r--r--src/db.h6
-rw-r--r--src/hash.cpp6
-rw-r--r--src/init.cpp255
-rw-r--r--src/main.cpp44
-rw-r--r--src/net.cpp12
-rw-r--r--src/net.h4
-rw-r--r--src/netbase.h2
-rw-r--r--src/pow.cpp10
-rw-r--r--src/pow.h1
-rw-r--r--src/primitives/block.cpp3
-rw-r--r--src/primitives/transaction.h3
-rw-r--r--src/protocol.cpp13
-rw-r--r--src/protocol.h8
-rw-r--r--src/qt/bitcoingui.cpp10
-rw-r--r--src/qt/bitcoingui.h4
-rw-r--r--src/qt/clientmodel.cpp18
-rw-r--r--src/qt/clientmodel.h5
-rw-r--r--src/qt/guiutil.cpp46
-rw-r--r--src/qt/rpcconsole.cpp9
-rw-r--r--src/qt/rpcconsole.h4
-rw-r--r--src/qt/sendcoinsdialog.cpp2
-rw-r--r--src/qt/utilitydialog.cpp78
-rw-r--r--src/script/script.h16
-rw-r--r--src/serialize.h201
-rw-r--r--src/test/Checkpoints_tests.cpp3
-rw-r--r--src/test/DoS_tests.cpp4
-rw-r--r--src/test/accounting_tests.cpp4
-rw-r--r--src/test/alert_tests.cpp4
-rw-r--r--src/test/allocator_tests.cpp3
-rw-r--r--src/test/arith_uint256_tests.cpp3
-rw-r--r--src/test/base32_tests.cpp3
-rw-r--r--src/test/base58_tests.cpp7
-rw-r--r--src/test/base64_tests.cpp3
-rw-r--r--src/test/bip32_tests.cpp3
-rw-r--r--src/test/bloom_tests.cpp3
-rw-r--r--src/test/checkblock_tests.cpp3
-rw-r--r--src/test/coins_tests.cpp3
-rw-r--r--src/test/compress_tests.cpp3
-rw-r--r--src/test/crypto_tests.cpp3
-rw-r--r--src/test/getarg_tests.cpp3
-rw-r--r--src/test/hash_tests.cpp3
-rw-r--r--src/test/key_tests.cpp3
-rw-r--r--src/test/main_tests.cpp4
-rw-r--r--src/test/miner_tests.cpp4
-rw-r--r--src/test/mruset_tests.cpp3
-rw-r--r--src/test/multisig_tests.cpp3
-rw-r--r--src/test/netbase_tests.cpp3
-rw-r--r--src/test/pmt_tests.cpp3
-rw-r--r--src/test/pow_tests.cpp67
-rw-r--r--src/test/rpc_tests.cpp4
-rw-r--r--src/test/rpc_wallet_tests.cpp4
-rw-r--r--src/test/sanity_tests.cpp4
-rw-r--r--src/test/script_P2SH_tests.cpp3
-rw-r--r--src/test/script_tests.cpp3
-rw-r--r--src/test/scriptnum_tests.cpp5
-rw-r--r--src/test/serialize_tests.cpp117
-rw-r--r--src/test/sighash_tests.cpp3
-rw-r--r--src/test/sigopcount_tests.cpp3
-rw-r--r--src/test/skiplist_tests.cpp3
-rw-r--r--src/test/test_bitcoin.cpp38
-rw-r--r--src/test/test_bitcoin.h30
-rw-r--r--src/test/timedata_tests.cpp3
-rw-r--r--src/test/transaction_tests.cpp3
-rw-r--r--src/test/uint256_tests.cpp3
-rw-r--r--src/test/univalue_tests.cpp3
-rw-r--r--src/test/util_tests.cpp3
-rw-r--r--src/test/wallet_tests.cpp4
-rw-r--r--src/txmempool.cpp4
-rw-r--r--src/util.cpp15
-rw-r--r--src/util.h18
-rw-r--r--src/walletdb.cpp6
86 files changed, 1154 insertions, 615 deletions
diff --git a/.travis.yml b/.travis.yml
index e08e78dabf..9c18729b42 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -10,6 +10,7 @@ env:
global:
- MAKEJOBS=-j3
- RUN_TESTS=false
+ - BOOST_TEST_RANDOM=1$TRAVIS_BUILD_ID
- CCACHE_SIZE=100M
- CCACHE_TEMPDIR=/tmp/.ccache-temp
- CCACHE_COMPRESS=1
diff --git a/configure.ac b/configure.ac
index f5bc1e3122..2c918218bb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -350,8 +350,8 @@ if test x$use_lcov = xyes; then
[AC_MSG_ERROR("lcov testing requested but --coverage flag does not work")])
fi
-dnl Require little endian
-AC_C_BIGENDIAN([AC_MSG_ERROR("Big Endian not supported")])
+dnl Check for endianness
+AC_C_BIGENDIAN
dnl Check for pthread compile/link requirements
AX_PTHREAD
@@ -438,17 +438,22 @@ if test x$TARGET_OS = xdarwin; then
AX_CHECK_LINK_FLAG([[-Wl,-dead_strip]], [LDFLAGS="$LDFLAGS -Wl,-dead_strip"])
fi
-AC_CHECK_HEADERS([endian.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h])
+AC_CHECK_HEADERS([endian.h byteswap.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h])
AC_SEARCH_LIBS([getaddrinfo_a], [anl], [AC_DEFINE(HAVE_GETADDRINFO_A, 1, [Define this symbol if you have getaddrinfo_a])])
AC_SEARCH_LIBS([inet_pton], [nsl resolv], [AC_DEFINE(HAVE_INET_PTON, 1, [Define this symbol if you have inet_pton])])
AC_CHECK_DECLS([strnlen])
-AC_CHECK_DECLS([le32toh, le64toh, htole32, htole64, be32toh, be64toh, htobe32, htobe64],,,
+AC_CHECK_DECLS([le16toh, le32toh, le64toh, htole16, htole32, htole64, be16toh, be32toh, be64toh, htobe16, htobe32, htobe64],,,
[#if HAVE_ENDIAN_H
#include <endian.h>
#endif])
+AC_CHECK_DECLS([bswap_16, bswap_32, bswap_64],,,
+ [#if HAVE_BYTESWAP_H
+ #include <byteswap.h>
+ #endif])
+
dnl Check for MSG_NOSIGNAL
AC_MSG_CHECKING(for MSG_NOSIGNAL)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/socket.h>]],
diff --git a/src/Makefile.am b/src/Makefile.am
index e1d467ff85..da65efa713 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -141,6 +141,8 @@ BITCOIN_CORE_H = \
walletdb.h \
wallet.h \
wallet_ismine.h \
+ compat/byteswap.h \
+ compat/endian.h \
compat/sanity.h
JSON_H = \
diff --git a/src/Makefile.test.include b/src/Makefile.test.include
index 90494439fa..e9d99323c5 100644
--- a/src/Makefile.test.include
+++ b/src/Makefile.test.include
@@ -55,6 +55,7 @@ BITCOIN_TESTS =\
test/multisig_tests.cpp \
test/netbase_tests.cpp \
test/pmt_tests.cpp \
+ test/pow_tests.cpp \
test/rpc_tests.cpp \
test/sanity_tests.cpp \
test/script_P2SH_tests.cpp \
@@ -65,6 +66,7 @@ BITCOIN_TESTS =\
test/sigopcount_tests.cpp \
test/skiplist_tests.cpp \
test/test_bitcoin.cpp \
+ test/test_bitcoin.h \
test/timedata_tests.cpp \
test/transaction_tests.cpp \
test/uint256_tests.cpp \
diff --git a/src/arith_uint256.cpp b/src/arith_uint256.cpp
index 1243823da5..2e61363576 100644
--- a/src/arith_uint256.cpp
+++ b/src/arith_uint256.cpp
@@ -7,6 +7,7 @@
#include "uint256.h"
#include "utilstrencodings.h"
+#include "crypto/common.h"
#include <stdio.h>
#include <string.h>
@@ -246,14 +247,14 @@ uint32_t arith_uint256::GetCompact(bool fNegative) const
uint256 ArithToUint256(const arith_uint256 &a)
{
uint256 b;
- // TODO: needs bswap32 on big-endian
- memcpy(b.begin(), a.pn, a.size());
+ for(int x=0; x<a.WIDTH; ++x)
+ WriteLE32(b.begin() + x*4, a.pn[x]);
return b;
}
arith_uint256 UintToArith256(const uint256 &a)
{
arith_uint256 b;
- // TODO: needs bswap32 on big-endian
- memcpy(b.pn, a.begin(), a.size());
+ for(int x=0; x<b.WIDTH; ++x)
+ b.pn[x] = ReadLE32(a.begin() + x*4);
return b;
}
diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp
index f273a15713..2fa8de6fd8 100644
--- a/src/bitcoin-cli.cpp
+++ b/src/bitcoin-cli.cpp
@@ -20,21 +20,21 @@ using namespace json_spirit;
std::string HelpMessageCli()
{
string strUsage;
- strUsage += _("Options:") + "\n";
- strUsage += " -? " + _("This help message") + "\n";
- strUsage += " -conf=<file> " + strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf") + "\n";
- strUsage += " -datadir=<dir> " + _("Specify data directory") + "\n";
- strUsage += " -testnet " + _("Use the test network") + "\n";
- strUsage += " -regtest " + _("Enter regression test mode, which uses a special chain in which blocks can be "
- "solved instantly. This is intended for regression testing tools and app development.") + "\n";
- strUsage += " -rpcconnect=<ip> " + strprintf(_("Send commands to node running on <ip> (default: %s)"), "127.0.0.1") + "\n";
- strUsage += " -rpcport=<port> " + strprintf(_("Connect to JSON-RPC on <port> (default: %u or testnet: %u)"), 8332, 18332) + "\n";
- strUsage += " -rpcwait " + _("Wait for RPC server to start") + "\n";
- strUsage += " -rpcuser=<user> " + _("Username for JSON-RPC connections") + "\n";
- strUsage += " -rpcpassword=<pw> " + _("Password for JSON-RPC connections") + "\n";
-
- strUsage += "\n" + _("SSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n";
- strUsage += " -rpcssl " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n";
+ strUsage += HelpMessageGroup(_("Options:"));
+ strUsage += HelpMessageOpt("-?", _("This help message"));
+ strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf"));
+ strUsage += HelpMessageOpt("-datadir=<dir>", _("Specify data directory"));
+ strUsage += HelpMessageOpt("-testnet", _("Use the test network"));
+ strUsage += HelpMessageOpt("-regtest", _("Enter regression test mode, which uses a special chain in which blocks can be "
+ "solved instantly. This is intended for regression testing tools and app development."));
+ strUsage += HelpMessageOpt("-rpcconnect=<ip>", strprintf(_("Send commands to node running on <ip> (default: %s)"), "127.0.0.1"));
+ strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Connect to JSON-RPC on <port> (default: %u or testnet: %u)"), 8332, 18332));
+ strUsage += HelpMessageOpt("-rpcwait", _("Wait for RPC server to start"));
+ strUsage += HelpMessageOpt("-rpcuser=<user>", _("Username for JSON-RPC connections"));
+ strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections"));
+
+ strUsage += HelpMessageGroup(_("SSL options: (see the Bitcoin Wiki for SSL setup instructions)"));
+ strUsage += HelpMessageOpt("-rpcssl", _("Use OpenSSL (https) for JSON-RPC connections"));
return strUsage;
}
diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp
index c1622cf5d3..78f5c2c4b6 100644
--- a/src/bitcoin-tx.cpp
+++ b/src/bitcoin-tx.cpp
@@ -54,38 +54,34 @@ static bool AppInitRawTx(int argc, char* argv[])
fprintf(stdout, "%s", strUsage.c_str());
- strUsage = _("Options:") + "\n";
- strUsage += " -? " + _("This help message") + "\n";
- strUsage += " -create " + _("Create new, empty TX.") + "\n";
- strUsage += " -json " + _("Select JSON output") + "\n";
- strUsage += " -txid " + _("Output only the hex-encoded transaction id of the resultant transaction.") + "\n";
- strUsage += " -regtest " + _("Enter regression test mode, which uses a special chain in which blocks can be solved instantly.") + "\n";
- strUsage += " -testnet " + _("Use the test network") + "\n";
- strUsage += "\n";
+ strUsage = HelpMessageGroup(_("Options:"));
+ strUsage += HelpMessageOpt("-?", _("This help message"));
+ strUsage += HelpMessageOpt("-create", _("Create new, empty TX."));
+ strUsage += HelpMessageOpt("-json", _("Select JSON output"));
+ strUsage += HelpMessageOpt("-txid", _("Output only the hex-encoded transaction id of the resultant transaction."));
+ strUsage += HelpMessageOpt("-regtest", _("Enter regression test mode, which uses a special chain in which blocks can be solved instantly."));
+ strUsage += HelpMessageOpt("-testnet", _("Use the test network"));
fprintf(stdout, "%s", strUsage.c_str());
-
- strUsage = _("Commands:") + "\n";
- strUsage += " delin=N " + _("Delete input N from TX") + "\n";
- strUsage += " delout=N " + _("Delete output N from TX") + "\n";
- strUsage += " in=TXID:VOUT " + _("Add input to TX") + "\n";
- strUsage += " locktime=N " + _("Set TX lock time to N") + "\n";
- strUsage += " nversion=N " + _("Set TX version to N") + "\n";
- strUsage += " outaddr=VALUE:ADDRESS " + _("Add address-based output to TX") + "\n";
- strUsage += " outscript=VALUE:SCRIPT " + _("Add raw script output to TX") + "\n";
- strUsage += " sign=SIGHASH-FLAGS " + _("Add zero or more signatures to transaction") + "\n";
- strUsage += " This command requires JSON registers:\n";
- strUsage += " prevtxs=JSON object\n";
- strUsage += " privatekeys=JSON object\n";
- strUsage += " See signrawtransaction docs for format of sighash flags, JSON objects.\n";
- strUsage += "\n";
+ strUsage = HelpMessageGroup(_("Commands:"));
+ strUsage += HelpMessageOpt("delin=N", _("Delete input N from TX"));
+ strUsage += HelpMessageOpt("delout=N", _("Delete output N from TX"));
+ strUsage += HelpMessageOpt("in=TXID:VOUT", _("Add input to TX"));
+ strUsage += HelpMessageOpt("locktime=N", _("Set TX lock time to N"));
+ strUsage += HelpMessageOpt("nversion=N", _("Set TX version to N"));
+ strUsage += HelpMessageOpt("outaddr=VALUE:ADDRESS", _("Add address-based output to TX"));
+ strUsage += HelpMessageOpt("outscript=VALUE:SCRIPT", _("Add raw script output to TX"));
+ strUsage += HelpMessageOpt("sign=SIGHASH-FLAGS", _("Add zero or more signatures to transaction") + ". " +
+ _("This command requires JSON registers:") +
+ _("prevtxs=JSON object") + ", " +
+ _("privatekeys=JSON object") + ". " +
+ _("See signrawtransaction docs for format of sighash flags, JSON objects."));
fprintf(stdout, "%s", strUsage.c_str());
- strUsage = _("Register Commands:") + "\n";
- strUsage += " load=NAME:FILENAME " + _("Load JSON file FILENAME into register NAME") + "\n";
- strUsage += " set=NAME:JSON-STRING " + _("Set register NAME to given JSON-STRING") + "\n";
- strUsage += "\n";
+ strUsage = HelpMessageGroup(_("Register Commands:"));
+ strUsage += HelpMessageOpt("load=NAME:FILENAME", _("Load JSON file FILENAME into register NAME"));
+ strUsage += HelpMessageOpt("set=NAME:JSON-STRING", _("Set register NAME to given JSON-STRING"));
fprintf(stdout, "%s", strUsage.c_str());
return false;
diff --git a/src/chainparams.cpp b/src/chainparams.cpp
index 1fd3b01681..2bc8976510 100644
--- a/src/chainparams.cpp
+++ b/src/chainparams.cpp
@@ -170,7 +170,6 @@ public:
fAllowMinDifficultyBlocks = false;
fRequireStandard = true;
fMineBlocksOnDemand = false;
- fSkipProofOfWorkCheck = false;
fTestnetToBeDeprecatedFieldRPC = false;
}
@@ -281,51 +280,8 @@ public:
};
static CRegTestParams regTestParams;
-/**
- * Unit test
- */
-class CUnitTestParams : public CMainParams, public CModifiableParams {
-public:
- CUnitTestParams() {
- strNetworkID = "unittest";
- nDefaultPort = 18445;
- vFixedSeeds.clear(); //! Unit test mode doesn't have any fixed seeds.
- vSeeds.clear(); //! Unit test mode doesn't have any DNS seeds.
-
- fRequireRPCPassword = false;
- fMiningRequiresPeers = false;
- fDefaultCheckMemPool = true;
- fAllowMinDifficultyBlocks = false;
- fMineBlocksOnDemand = true;
- }
-
- const Checkpoints::CCheckpointData& Checkpoints() const
- {
- // UnitTest share the same checkpoints as MAIN
- return data;
- }
-
- //! Published setters to allow changing values in unit test cases
- virtual void setSubsidyHalvingInterval(int anSubsidyHalvingInterval) { nSubsidyHalvingInterval=anSubsidyHalvingInterval; }
- virtual void setEnforceBlockUpgradeMajority(int anEnforceBlockUpgradeMajority) { nEnforceBlockUpgradeMajority=anEnforceBlockUpgradeMajority; }
- virtual void setRejectBlockOutdatedMajority(int anRejectBlockOutdatedMajority) { nRejectBlockOutdatedMajority=anRejectBlockOutdatedMajority; }
- virtual void setToCheckBlockUpgradeMajority(int anToCheckBlockUpgradeMajority) { nToCheckBlockUpgradeMajority=anToCheckBlockUpgradeMajority; }
- virtual void setDefaultCheckMemPool(bool afDefaultCheckMemPool) { fDefaultCheckMemPool=afDefaultCheckMemPool; }
- virtual void setAllowMinDifficultyBlocks(bool afAllowMinDifficultyBlocks) { fAllowMinDifficultyBlocks=afAllowMinDifficultyBlocks; }
- virtual void setSkipProofOfWorkCheck(bool afSkipProofOfWorkCheck) { fSkipProofOfWorkCheck = afSkipProofOfWorkCheck; }
-};
-static CUnitTestParams unitTestParams;
-
-
static CChainParams *pCurrentParams = 0;
-CModifiableParams *ModifiableParams()
-{
- assert(pCurrentParams);
- assert(pCurrentParams==&unitTestParams);
- return (CModifiableParams*)&unitTestParams;
-}
-
const CChainParams &Params() {
assert(pCurrentParams);
return *pCurrentParams;
@@ -339,8 +295,6 @@ CChainParams &Params(CBaseChainParams::Network network) {
return testNetParams;
case CBaseChainParams::REGTEST:
return regTestParams;
- case CBaseChainParams::UNITTEST:
- return unitTestParams;
default:
assert(false && "Unimplemented network");
return mainParams;
diff --git a/src/chainparams.h b/src/chainparams.h
index 86b84df667..134dcd6558 100644
--- a/src/chainparams.h
+++ b/src/chainparams.h
@@ -14,8 +14,6 @@
#include <vector>
-typedef unsigned char MessageStartChars[MESSAGE_START_SIZE];
-
struct CDNSSeedData {
std::string name, host;
CDNSSeedData(const std::string &strName, const std::string &strHost) : name(strName), host(strHost) {}
@@ -42,7 +40,7 @@ public:
};
const uint256& HashGenesisBlock() const { return hashGenesisBlock; }
- const MessageStartChars& MessageStart() const { return pchMessageStart; }
+ const CMessageHeader::MessageStartChars& MessageStart() const { return pchMessageStart; }
const std::vector<unsigned char>& AlertKey() const { return vAlertPubKey; }
int GetDefaultPort() const { return nDefaultPort; }
const arith_uint256& ProofOfWorkLimit() const { return bnProofOfWorkLimit; }
@@ -62,8 +60,6 @@ public:
bool DefaultCheckMemPool() const { return fDefaultCheckMemPool; }
/** Allow mining of a min-difficulty block */
bool AllowMinDifficultyBlocks() const { return fAllowMinDifficultyBlocks; }
- /** Skip proof-of-work check: allow mining of any difficulty block */
- bool SkipProofOfWorkCheck() const { return fSkipProofOfWorkCheck; }
/** Make standard checks */
bool RequireStandard() const { return fRequireStandard; }
int64_t TargetTimespan() const { return nTargetTimespan; }
@@ -83,7 +79,7 @@ protected:
CChainParams() {}
uint256 hashGenesisBlock;
- MessageStartChars pchMessageStart;
+ CMessageHeader::MessageStartChars pchMessageStart;
//! Raw pub key bytes for the broadcast alert signing key.
std::vector<unsigned char> vAlertPubKey;
int nDefaultPort;
@@ -106,29 +102,9 @@ protected:
bool fAllowMinDifficultyBlocks;
bool fRequireStandard;
bool fMineBlocksOnDemand;
- bool fSkipProofOfWorkCheck;
bool fTestnetToBeDeprecatedFieldRPC;
};
-/**
- * Modifiable parameters interface is used by test cases to adapt the parameters in order
- * to test specific features more easily. Test cases should always restore the previous
- * values after finalization.
- */
-
-class CModifiableParams {
-public:
- //! Published setters to allow changing values in unit test cases
- virtual void setSubsidyHalvingInterval(int anSubsidyHalvingInterval) =0;
- virtual void setEnforceBlockUpgradeMajority(int anEnforceBlockUpgradeMajority)=0;
- virtual void setRejectBlockOutdatedMajority(int anRejectBlockOutdatedMajority)=0;
- virtual void setToCheckBlockUpgradeMajority(int anToCheckBlockUpgradeMajority)=0;
- virtual void setDefaultCheckMemPool(bool aDefaultCheckMemPool)=0;
- virtual void setAllowMinDifficultyBlocks(bool aAllowMinDifficultyBlocks)=0;
- virtual void setSkipProofOfWorkCheck(bool aSkipProofOfWorkCheck)=0;
-};
-
-
/**
* Return the currently selected parameters. This won't change after app startup
* outside of the unit tests.
@@ -138,9 +114,6 @@ const CChainParams &Params();
/** Return parameters for the given network. */
CChainParams &Params(CBaseChainParams::Network network);
-/** Get modifiable network parameters (UNITTEST only) */
-CModifiableParams *ModifiableParams();
-
/** Sets the params returned by Params() to those for the given network. */
void SelectParams(CBaseChainParams::Network network);
diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp
index c42fd106be..7d82d689ec 100644
--- a/src/chainparamsbase.cpp
+++ b/src/chainparamsbase.cpp
@@ -82,9 +82,6 @@ void SelectBaseParams(CBaseChainParams::Network network)
case CBaseChainParams::REGTEST:
pCurrentBaseParams = &regTestParams;
break;
- case CBaseChainParams::UNITTEST:
- pCurrentBaseParams = &unitTestParams;
- break;
default:
assert(false && "Unimplemented network");
return;
diff --git a/src/chainparamsbase.h b/src/chainparamsbase.h
index cebe7aa01a..421a3a06ff 100644
--- a/src/chainparamsbase.h
+++ b/src/chainparamsbase.h
@@ -19,7 +19,6 @@ public:
MAIN,
TESTNET,
REGTEST,
- UNITTEST,
MAX_NETWORK_TYPES
};
diff --git a/src/compat/byteswap.h b/src/compat/byteswap.h
new file mode 100644
index 0000000000..899220bdc5
--- /dev/null
+++ b/src/compat/byteswap.h
@@ -0,0 +1,47 @@
+// Copyright (c) 2014 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_COMPAT_BYTESWAP_H
+#define BITCOIN_COMPAT_BYTESWAP_H
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include <stdint.h>
+
+#if defined(HAVE_BYTESWAP_H)
+#include <byteswap.h>
+#endif
+
+#if HAVE_DECL_BSWAP_16 == 0
+inline uint16_t bswap_16(uint16_t x)
+{
+ return (x >> 8) | ((x & 0x00ff) << 8);
+}
+#endif // HAVE_DECL_BSWAP16
+
+#if HAVE_DECL_BSWAP_32 == 0
+inline uint32_t bswap_32(uint32_t x)
+{
+ return (((x & 0xff000000U) >> 24) | ((x & 0x00ff0000U) >> 8) |
+ ((x & 0x0000ff00U) << 8) | ((x & 0x000000ffU) << 24));
+}
+#endif // HAVE_DECL_BSWAP32
+
+#if HAVE_DECL_BSWAP_64 == 0
+inline uint64_t bswap_64(uint64_t x)
+{
+ return (((x & 0xff00000000000000ull) >> 56)
+ | ((x & 0x00ff000000000000ull) >> 40)
+ | ((x & 0x0000ff0000000000ull) >> 24)
+ | ((x & 0x000000ff00000000ull) >> 8)
+ | ((x & 0x00000000ff000000ull) << 8)
+ | ((x & 0x0000000000ff0000ull) << 24)
+ | ((x & 0x000000000000ff00ull) << 40)
+ | ((x & 0x00000000000000ffull) << 56));
+}
+#endif // HAVE_DECL_BSWAP64
+
+#endif // BITCOIN_COMPAT_BYTESWAP_H
diff --git a/src/compat/endian.h b/src/compat/endian.h
new file mode 100644
index 0000000000..4d041d6554
--- /dev/null
+++ b/src/compat/endian.h
@@ -0,0 +1,194 @@
+// Copyright (c) 2014 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_COMPAT_ENDIAN_H
+#define BITCOIN_COMPAT_ENDIAN_H
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include <stdint.h>
+
+#include "compat/byteswap.h"
+
+#if defined(HAVE_ENDIAN_H)
+#include <endian.h>
+#endif
+
+#if defined(WORDS_BIGENDIAN)
+
+#if HAVE_DECL_HTOBE16 == 0
+inline uint16_t htobe16(uint16_t host_16bits)
+{
+ return host_16bits;
+}
+#endif // HAVE_DECL_HTOBE16
+
+#if HAVE_DECL_HTOLE16 == 0
+inline uint16_t htole16(uint16_t host_16bits)
+{
+ return bswap_16(host_16bits);
+}
+#endif // HAVE_DECL_HTOLE16
+
+#if HAVE_DECL_BE16TOH == 0
+inline uint16_t be16toh(uint16_t big_endian_16bits)
+{
+ return big_endian_16bits;
+}
+#endif // HAVE_DECL_BE16TOH
+
+#if HAVE_DECL_LE16TOH == 0
+inline uint16_t le16toh(uint16_t little_endian_16bits)
+{
+ return bswap_16(little_endian_16bits);
+}
+#endif // HAVE_DECL_LE16TOH
+
+#if HAVE_DECL_HTOBE32 == 0
+inline uint32_t htobe32(uint32_t host_32bits)
+{
+ return host_32bits;
+}
+#endif // HAVE_DECL_HTOBE32
+
+#if HAVE_DECL_HTOLE32 == 0
+inline uint32_t htole32(uint32_t host_32bits)
+{
+ return bswap_32(host_32bits);
+}
+#endif // HAVE_DECL_HTOLE32
+
+#if HAVE_DECL_BE32TOH == 0
+inline uint32_t be32toh(uint32_t big_endian_32bits)
+{
+ return big_endian_32bits;
+}
+#endif // HAVE_DECL_BE32TOH
+
+#if HAVE_DECL_LE32TOH == 0
+inline uint32_t le32toh(uint32_t little_endian_32bits)
+{
+ return bswap_32(little_endian_32bits);
+}
+#endif // HAVE_DECL_LE32TOH
+
+#if HAVE_DECL_HTOBE64 == 0
+inline uint64_t htobe64(uint64_t host_64bits)
+{
+ return host_64bits;
+}
+#endif // HAVE_DECL_HTOBE64
+
+#if HAVE_DECL_HTOLE64 == 0
+inline uint64_t htole64(uint64_t host_64bits)
+{
+ return bswap_64(host_64bits);
+}
+#endif // HAVE_DECL_HTOLE64
+
+#if HAVE_DECL_BE64TOH == 0
+inline uint64_t be64toh(uint64_t big_endian_64bits)
+{
+ return big_endian_64bits;
+}
+#endif // HAVE_DECL_BE64TOH
+
+#if HAVE_DECL_LE64TOH == 0
+inline uint64_t le64toh(uint64_t little_endian_64bits)
+{
+ return bswap_64(little_endian_64bits);
+}
+#endif // HAVE_DECL_LE64TOH
+
+#else // WORDS_BIGENDIAN
+
+#if HAVE_DECL_HTOBE16 == 0
+inline uint16_t htobe16(uint16_t host_16bits)
+{
+ return bswap_16(host_16bits);
+}
+#endif // HAVE_DECL_HTOBE16
+
+#if HAVE_DECL_HTOLE16 == 0
+inline uint16_t htole16(uint16_t host_16bits)
+{
+ return host_16bits;
+}
+#endif // HAVE_DECL_HTOLE16
+
+#if HAVE_DECL_BE16TOH == 0
+inline uint16_t be16toh(uint16_t big_endian_16bits)
+{
+ return bswap_16(big_endian_16bits);
+}
+#endif // HAVE_DECL_BE16TOH
+
+#if HAVE_DECL_LE16TOH == 0
+inline uint16_t le16toh(uint16_t little_endian_16bits)
+{
+ return little_endian_16bits;
+}
+#endif // HAVE_DECL_LE16TOH
+
+#if HAVE_DECL_HTOBE32 == 0
+inline uint32_t htobe32(uint32_t host_32bits)
+{
+ return bswap_32(host_32bits);
+}
+#endif // HAVE_DECL_HTOBE32
+
+#if HAVE_DECL_HTOLE32 == 0
+inline uint32_t htole32(uint32_t host_32bits)
+{
+ return host_32bits;
+}
+#endif // HAVE_DECL_HTOLE32
+
+#if HAVE_DECL_BE32TOH == 0
+inline uint32_t be32toh(uint32_t big_endian_32bits)
+{
+ return bswap_32(big_endian_32bits);
+}
+#endif // HAVE_DECL_BE32TOH
+
+#if HAVE_DECL_LE32TOH == 0
+inline uint32_t le32toh(uint32_t little_endian_32bits)
+{
+ return little_endian_32bits;
+}
+#endif // HAVE_DECL_LE32TOH
+
+#if HAVE_DECL_HTOBE64 == 0
+inline uint64_t htobe64(uint64_t host_64bits)
+{
+ return bswap_64(host_64bits);
+}
+#endif // HAVE_DECL_HTOBE64
+
+#if HAVE_DECL_HTOLE64 == 0
+inline uint64_t htole64(uint64_t host_64bits)
+{
+ return host_64bits;
+}
+#endif // HAVE_DECL_HTOLE64
+
+#if HAVE_DECL_BE64TOH == 0
+inline uint64_t be64toh(uint64_t big_endian_64bits)
+{
+ return bswap_64(big_endian_64bits);
+}
+#endif // HAVE_DECL_BE64TOH
+
+#if HAVE_DECL_LE64TOH == 0
+inline uint64_t le64toh(uint64_t little_endian_64bits)
+{
+ return little_endian_64bits;
+}
+#endif // HAVE_DECL_LE64TOH
+
+#endif // WORDS_BIGENDIAN
+
+#endif // BITCOIN_COMPAT_ENDIAN_H
diff --git a/src/crypto/common.h b/src/crypto/common.h
index 8b04b1f728..580c72f5a6 100644
--- a/src/crypto/common.h
+++ b/src/crypto/common.h
@@ -11,110 +11,56 @@
#include <stdint.h>
-#if defined(HAVE_ENDIAN_H)
-#include <endian.h>
-#endif
+#include "compat/endian.h"
+
+uint16_t static inline ReadLE16(const unsigned char* ptr)
+{
+ return le16toh(*((uint16_t*)ptr));
+}
uint32_t static inline ReadLE32(const unsigned char* ptr)
{
-#if HAVE_DECL_LE32TOH == 1
return le32toh(*((uint32_t*)ptr));
-#elif !defined(WORDS_BIGENDIAN)
- return *((uint32_t*)ptr);
-#else
- return ((uint32_t)ptr[3] << 24 | (uint32_t)ptr[2] << 16 | (uint32_t)ptr[1] << 8 | (uint32_t)ptr[0]);
-#endif
}
uint64_t static inline ReadLE64(const unsigned char* ptr)
{
-#if HAVE_DECL_LE64TOH == 1
return le64toh(*((uint64_t*)ptr));
-#elif !defined(WORDS_BIGENDIAN)
- return *((uint64_t*)ptr);
-#else
- return ((uint64_t)ptr[7] << 56 | (uint64_t)ptr[6] << 48 | (uint64_t)ptr[5] << 40 | (uint64_t)ptr[4] << 32 |
- (uint64_t)ptr[3] << 24 | (uint64_t)ptr[2] << 16 | (uint64_t)ptr[1] << 8 | (uint64_t)ptr[0]);
-#endif
+}
+
+void static inline WriteLE16(unsigned char* ptr, uint16_t x)
+{
+ *((uint16_t*)ptr) = htole16(x);
}
void static inline WriteLE32(unsigned char* ptr, uint32_t x)
{
-#if HAVE_DECL_HTOLE32 == 1
*((uint32_t*)ptr) = htole32(x);
-#elif !defined(WORDS_BIGENDIAN)
- *((uint32_t*)ptr) = x;
-#else
- ptr[3] = x >> 24;
- ptr[2] = x >> 16;
- ptr[1] = x >> 8;
- ptr[0] = x;
-#endif
}
void static inline WriteLE64(unsigned char* ptr, uint64_t x)
{
-#if HAVE_DECL_HTOLE64 == 1
*((uint64_t*)ptr) = htole64(x);
-#elif !defined(WORDS_BIGENDIAN)
- *((uint64_t*)ptr) = x;
-#else
- ptr[7] = x >> 56;
- ptr[6] = x >> 48;
- ptr[5] = x >> 40;
- ptr[4] = x >> 32;
- ptr[3] = x >> 24;
- ptr[2] = x >> 16;
- ptr[1] = x >> 8;
- ptr[0] = x;
-#endif
}
uint32_t static inline ReadBE32(const unsigned char* ptr)
{
-#if HAVE_DECL_BE32TOH == 1
return be32toh(*((uint32_t*)ptr));
-#else
- return ((uint32_t)ptr[0] << 24 | (uint32_t)ptr[1] << 16 | (uint32_t)ptr[2] << 8 | (uint32_t)ptr[3]);
-#endif
}
uint64_t static inline ReadBE64(const unsigned char* ptr)
{
-#if HAVE_DECL_BE64TOH == 1
return be64toh(*((uint64_t*)ptr));
-#else
- return ((uint64_t)ptr[0] << 56 | (uint64_t)ptr[1] << 48 | (uint64_t)ptr[2] << 40 | (uint64_t)ptr[3] << 32 |
- (uint64_t)ptr[4] << 24 | (uint64_t)ptr[5] << 16 | (uint64_t)ptr[6] << 8 | (uint64_t)ptr[7]);
-#endif
}
void static inline WriteBE32(unsigned char* ptr, uint32_t x)
{
-#if HAVE_DECL_HTOBE32 == 1
*((uint32_t*)ptr) = htobe32(x);
-#else
- ptr[0] = x >> 24;
- ptr[1] = x >> 16;
- ptr[2] = x >> 8;
- ptr[3] = x;
-#endif
}
void static inline WriteBE64(unsigned char* ptr, uint64_t x)
{
-#if HAVE_DECL_HTOBE64 == 1
*((uint64_t*)ptr) = htobe64(x);
-#else
- ptr[0] = x >> 56;
- ptr[1] = x >> 48;
- ptr[2] = x >> 40;
- ptr[3] = x >> 32;
- ptr[4] = x >> 24;
- ptr[5] = x >> 16;
- ptr[6] = x >> 8;
- ptr[7] = x;
-#endif
}
#endif // BITCOIN_CRYPTO_COMMON_H
diff --git a/src/db.cpp b/src/db.cpp
index 3246e4b67a..36946b7dcc 100644
--- a/src/db.cpp
+++ b/src/db.cpp
@@ -39,22 +39,31 @@ void CDBEnv::EnvShutdown()
return;
fDbEnvInit = false;
- int ret = dbenv.close(0);
+ int ret = dbenv->close(0);
if (ret != 0)
LogPrintf("CDBEnv::EnvShutdown: Error %d shutting down database environment: %s\n", ret, DbEnv::strerror(ret));
if (!fMockDb)
DbEnv(0).remove(path.string().c_str(), 0);
}
-CDBEnv::CDBEnv() : dbenv(DB_CXX_NO_EXCEPTIONS)
+void CDBEnv::Reset()
{
+ delete dbenv;
+ dbenv = new DbEnv(DB_CXX_NO_EXCEPTIONS);
fDbEnvInit = false;
fMockDb = false;
}
+CDBEnv::CDBEnv() : dbenv(NULL)
+{
+ Reset();
+}
+
CDBEnv::~CDBEnv()
{
EnvShutdown();
+ delete dbenv;
+ dbenv = NULL;
}
void CDBEnv::Close()
@@ -79,17 +88,17 @@ bool CDBEnv::Open(const boost::filesystem::path& pathIn)
if (GetBoolArg("-privdb", true))
nEnvFlags |= DB_PRIVATE;
- dbenv.set_lg_dir(pathLogDir.string().c_str());
- dbenv.set_cachesize(0, 0x100000, 1); // 1 MiB should be enough for just the wallet
- dbenv.set_lg_bsize(0x10000);
- dbenv.set_lg_max(1048576);
- dbenv.set_lk_max_locks(40000);
- dbenv.set_lk_max_objects(40000);
- dbenv.set_errfile(fopen(pathErrorFile.string().c_str(), "a")); /// debug
- dbenv.set_flags(DB_AUTO_COMMIT, 1);
- dbenv.set_flags(DB_TXN_WRITE_NOSYNC, 1);
- dbenv.log_set_config(DB_LOG_AUTO_REMOVE, 1);
- int ret = dbenv.open(path.string().c_str(),
+ dbenv->set_lg_dir(pathLogDir.string().c_str());
+ dbenv->set_cachesize(0, 0x100000, 1); // 1 MiB should be enough for just the wallet
+ dbenv->set_lg_bsize(0x10000);
+ dbenv->set_lg_max(1048576);
+ dbenv->set_lk_max_locks(40000);
+ dbenv->set_lk_max_objects(40000);
+ dbenv->set_errfile(fopen(pathErrorFile.string().c_str(), "a")); /// debug
+ dbenv->set_flags(DB_AUTO_COMMIT, 1);
+ dbenv->set_flags(DB_TXN_WRITE_NOSYNC, 1);
+ dbenv->log_set_config(DB_LOG_AUTO_REMOVE, 1);
+ int ret = dbenv->open(path.string().c_str(),
DB_CREATE |
DB_INIT_LOCK |
DB_INIT_LOG |
@@ -116,14 +125,14 @@ void CDBEnv::MakeMock()
LogPrint("db", "CDBEnv::MakeMock\n");
- dbenv.set_cachesize(1, 0, 1);
- dbenv.set_lg_bsize(10485760 * 4);
- dbenv.set_lg_max(10485760);
- dbenv.set_lk_max_locks(10000);
- dbenv.set_lk_max_objects(10000);
- dbenv.set_flags(DB_AUTO_COMMIT, 1);
- dbenv.log_set_config(DB_LOG_IN_MEMORY, 1);
- int ret = dbenv.open(NULL,
+ dbenv->set_cachesize(1, 0, 1);
+ dbenv->set_lg_bsize(10485760 * 4);
+ dbenv->set_lg_max(10485760);
+ dbenv->set_lk_max_locks(10000);
+ dbenv->set_lk_max_objects(10000);
+ dbenv->set_flags(DB_AUTO_COMMIT, 1);
+ dbenv->log_set_config(DB_LOG_IN_MEMORY, 1);
+ int ret = dbenv->open(NULL,
DB_CREATE |
DB_INIT_LOCK |
DB_INIT_LOG |
@@ -144,7 +153,7 @@ CDBEnv::VerifyResult CDBEnv::Verify(std::string strFile, bool (*recoverFunc)(CDB
LOCK(cs_db);
assert(mapFileUseCount.count(strFile) == 0);
- Db db(&dbenv, 0);
+ Db db(dbenv, 0);
int result = db.verify(strFile.c_str(), NULL, NULL, 0);
if (result == 0)
return VERIFY_OK;
@@ -167,7 +176,7 @@ bool CDBEnv::Salvage(std::string strFile, bool fAggressive, std::vector<CDBEnv::
stringstream strDump;
- Db db(&dbenv, 0);
+ Db db(dbenv, 0);
int result = db.verify(strFile.c_str(), NULL, &strDump, flags);
if (result == DB_VERIFY_BAD) {
LogPrintf("CDBEnv::Salvage: Database salvage found errors, all data may not be recoverable.\n");
@@ -208,10 +217,10 @@ bool CDBEnv::Salvage(std::string strFile, bool fAggressive, std::vector<CDBEnv::
void CDBEnv::CheckpointLSN(const std::string& strFile)
{
- dbenv.txn_checkpoint(0, 0, 0);
+ dbenv->txn_checkpoint(0, 0, 0);
if (fMockDb)
return;
- dbenv.lsn_reset(strFile.c_str(), 0);
+ dbenv->lsn_reset(strFile.c_str(), 0);
}
@@ -237,7 +246,7 @@ CDB::CDB(const std::string& strFilename, const char* pszMode, bool fFlushOnClose
++bitdb.mapFileUseCount[strFile];
pdb = bitdb.mapDb[strFile];
if (pdb == NULL) {
- pdb = new Db(&bitdb.dbenv, 0);
+ pdb = new Db(bitdb.dbenv, 0);
bool fMockDb = bitdb.IsMock();
if (fMockDb) {
@@ -284,7 +293,7 @@ void CDB::Flush()
if (fReadOnly)
nMinutes = 1;
- bitdb.dbenv.txn_checkpoint(nMinutes ? GetArg("-dblogsize", 100) * 1024 : 0, nMinutes, 0);
+ bitdb.dbenv->txn_checkpoint(nMinutes ? GetArg("-dblogsize", 100) * 1024 : 0, nMinutes, 0);
}
void CDB::Close()
@@ -324,7 +333,7 @@ bool CDBEnv::RemoveDb(const string& strFile)
this->CloseDb(strFile);
LOCK(cs_db);
- int rc = dbenv.dbremove(NULL, strFile.c_str(), NULL, DB_AUTO_COMMIT);
+ int rc = dbenv->dbremove(NULL, strFile.c_str(), NULL, DB_AUTO_COMMIT);
return (rc == 0);
}
@@ -344,7 +353,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip)
string strFileRes = strFile + ".rewrite";
{ // surround usage of db with extra {}
CDB db(strFile.c_str(), "r");
- Db* pdbCopy = new Db(&bitdb.dbenv, 0);
+ Db* pdbCopy = new Db(bitdb.dbenv, 0);
int ret = pdbCopy->open(NULL, // Txn pointer
strFileRes.c_str(), // Filename
@@ -394,10 +403,10 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip)
}
}
if (fSuccess) {
- Db dbA(&bitdb.dbenv, 0);
+ Db dbA(bitdb.dbenv, 0);
if (dbA.remove(strFile.c_str(), NULL, 0))
fSuccess = false;
- Db dbB(&bitdb.dbenv, 0);
+ Db dbB(bitdb.dbenv, 0);
if (dbB.rename(strFileRes.c_str(), NULL, strFile.c_str(), 0))
fSuccess = false;
}
@@ -430,10 +439,10 @@ void CDBEnv::Flush(bool fShutdown)
// Move log data to the dat file
CloseDb(strFile);
LogPrint("db", "CDBEnv::Flush: %s checkpoint\n", strFile);
- dbenv.txn_checkpoint(0, 0, 0);
+ dbenv->txn_checkpoint(0, 0, 0);
LogPrint("db", "CDBEnv::Flush: %s detach\n", strFile);
if (!fMockDb)
- dbenv.lsn_reset(strFile.c_str(), 0);
+ dbenv->lsn_reset(strFile.c_str(), 0);
LogPrint("db", "CDBEnv::Flush: %s closed\n", strFile);
mapFileUseCount.erase(mi++);
} else
@@ -443,7 +452,7 @@ void CDBEnv::Flush(bool fShutdown)
if (fShutdown) {
char** listp;
if (mapFileUseCount.empty()) {
- dbenv.log_archive(&listp, DB_ARCH_REMOVE);
+ dbenv->log_archive(&listp, DB_ARCH_REMOVE);
Close();
if (!fMockDb)
boost::filesystem::remove_all(path / "database");
diff --git a/src/db.h b/src/db.h
index d208907c89..71133f9699 100644
--- a/src/db.h
+++ b/src/db.h
@@ -39,12 +39,14 @@ private:
public:
mutable CCriticalSection cs_db;
- DbEnv dbenv;
+ DbEnv *dbenv;
std::map<std::string, int> mapFileUseCount;
std::map<std::string, Db*> mapDb;
CDBEnv();
~CDBEnv();
+ void Reset();
+
void MakeMock();
bool IsMock() { return fMockDb; }
@@ -79,7 +81,7 @@ public:
DbTxn* TxnBegin(int flags = DB_TXN_WRITE_NOSYNC)
{
DbTxn* ptxn = NULL;
- int ret = dbenv.txn_begin(NULL, &ptxn, flags);
+ int ret = dbenv->txn_begin(NULL, &ptxn, flags);
if (!ptxn || ret != 0)
return NULL;
return ptxn;
diff --git a/src/hash.cpp b/src/hash.cpp
index a7eb5a2a0b..20d5d21777 100644
--- a/src/hash.cpp
+++ b/src/hash.cpp
@@ -3,8 +3,10 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "hash.h"
+#include "crypto/common.h"
#include "crypto/hmac_sha512.h"
+
inline uint32_t ROTL32(uint32_t x, int8_t r)
{
return (x << r) | (x >> (32 - r));
@@ -23,10 +25,10 @@ unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char
//----------
// body
- const uint32_t* blocks = (const uint32_t*)(&vDataToHash[0] + nblocks * 4);
+ const uint8_t* blocks = &vDataToHash[0] + nblocks * 4;
for (int i = -nblocks; i; i++) {
- uint32_t k1 = blocks[i];
+ uint32_t k1 = ReadLE32(blocks + i*4);
k1 *= c1;
k1 = ROTL32(k1, 15);
diff --git a/src/init.cpp b/src/init.cpp
index c8f32d8bfd..1e3cc1d899 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -256,157 +256,174 @@ void OnRPCPreCommand(const CRPCCommand& cmd)
std::string HelpMessage(HelpMessageMode mode)
{
+
// When adding new options to the categories, please keep and ensure alphabetical ordering.
- string strUsage = _("Options:") + "\n";
- strUsage += " -? " + _("This help message") + "\n";
- strUsage += " -alertnotify=<cmd> " + _("Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)") + "\n";
- strUsage += " -blocknotify=<cmd> " + _("Execute command when the best block changes (%s in cmd is replaced by block hash)") + "\n";
- strUsage += " -checkblocks=<n> " + strprintf(_("How many blocks to check at startup (default: %u, 0 = all)"), 288) + "\n";
- strUsage += " -checklevel=<n> " + strprintf(_("How thorough the block verification of -checkblocks is (0-4, default: %u)"), 3) + "\n";
- strUsage += " -conf=<file> " + strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf") + "\n";
+ string strUsage = HelpMessageGroup(_("Options:"));
+ strUsage += HelpMessageOpt("-?", _("This help message"));
+ strUsage += HelpMessageOpt("-alertnotify=<cmd>", _("Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)"));
+ strUsage += HelpMessageOpt("-blocknotify=<cmd>", _("Execute command when the best block changes (%s in cmd is replaced by block hash)"));
+ strUsage += HelpMessageOpt("-checkblocks=<n>", strprintf(_("How many blocks to check at startup (default: %u, 0 = all)"), 288));
+ strUsage += HelpMessageOpt("-checklevel=<n>", strprintf(_("How thorough the block verification of -checkblocks is (0-4, default: %u)"), 3));
+ strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf"));
if (mode == HMM_BITCOIND)
{
#if !defined(WIN32)
- strUsage += " -daemon " + _("Run in the background as a daemon and accept commands") + "\n";
+ strUsage += HelpMessageOpt("-daemon", _("Run in the background as a daemon and accept commands"));
#endif
}
- strUsage += " -datadir=<dir> " + _("Specify data directory") + "\n";
- strUsage += " -dbcache=<n> " + strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache) + "\n";
- strUsage += " -loadblock=<file> " + _("Imports blocks from external blk000??.dat file") + " " + _("on startup") + "\n";
- strUsage += " -maxorphantx=<n> " + strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS) + "\n";
- strUsage += " -par=<n> " + strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"), -(int)boost::thread::hardware_concurrency(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS) + "\n";
+ strUsage += HelpMessageOpt("-datadir=<dir>", _("Specify data directory"));
+ strUsage += HelpMessageOpt("-dbcache=<n>", strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache));
+ strUsage += HelpMessageOpt("-loadblock=<file>", _("Imports blocks from external blk000??.dat file") + " " + _("on startup"));
+ strUsage += HelpMessageOpt("-maxorphantx=<n>", strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS));
+ strUsage += HelpMessageOpt("-par=<n>", strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"),
+ -(int)boost::thread::hardware_concurrency(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS));
#ifndef WIN32
- strUsage += " -pid=<file> " + strprintf(_("Specify pid file (default: %s)"), "bitcoind.pid") + "\n";
+ strUsage += HelpMessageOpt("-pid=<file>", strprintf(_("Specify pid file (default: %s)"), "bitcoind.pid"));
#endif
- strUsage += " -reindex " + _("Rebuild block chain index from current blk000??.dat files") + " " + _("on startup") + "\n";
+ strUsage += HelpMessageOpt("-reindex", _("Rebuild block chain index from current blk000??.dat files") + " " + _("on startup"));
#if !defined(WIN32)
- strUsage += " -sysperms " + _("Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)") + "\n";
+ strUsage += HelpMessageOpt("-sysperms", _("Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)"));
#endif
- strUsage += " -txindex " + strprintf(_("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)"), 0) + "\n";
-
- strUsage += "\n" + _("Connection options:") + "\n";
- strUsage += " -addnode=<ip> " + _("Add a node to connect to and attempt to keep the connection open") + "\n";
- strUsage += " -banscore=<n> " + strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), 100) + "\n";
- strUsage += " -bantime=<n> " + strprintf(_("Number of seconds to keep misbehaving peers from reconnecting (default: %u)"), 86400) + "\n";
- strUsage += " -bind=<addr> " + _("Bind to given address and always listen on it. Use [host]:port notation for IPv6") + "\n";
- strUsage += " -connect=<ip> " + _("Connect only to the specified node(s)") + "\n";
- strUsage += " -discover " + _("Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)") + "\n";
- strUsage += " -dns " + _("Allow DNS lookups for -addnode, -seednode and -connect") + " " + _("(default: 1)") + "\n";
- strUsage += " -dnsseed " + _("Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)") + "\n";
- strUsage += " -externalip=<ip> " + _("Specify your own public address") + "\n";
- strUsage += " -forcednsseed " + strprintf(_("Always query for peer addresses via DNS lookup (default: %u)"), 0) + "\n";
- strUsage += " -listen " + _("Accept connections from outside (default: 1 if no -proxy or -connect)") + "\n";
- strUsage += " -maxconnections=<n> " + strprintf(_("Maintain at most <n> connections to peers (default: %u)"), 125) + "\n";
- strUsage += " -maxreceivebuffer=<n> " + strprintf(_("Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)"), 5000) + "\n";
- strUsage += " -maxsendbuffer=<n> " + strprintf(_("Maximum per-connection send buffer, <n>*1000 bytes (default: %u)"), 1000) + "\n";
- strUsage += " -onion=<ip:port> " + strprintf(_("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)"), "-proxy") + "\n";
- strUsage += " -onlynet=<net> " + _("Only connect to nodes in network <net> (ipv4, ipv6 or onion)") + "\n";
- strUsage += " -permitbaremultisig " + strprintf(_("Relay non-P2SH multisig (default: %u)"), 1) + "\n";
- strUsage += " -port=<port> " + strprintf(_("Listen for connections on <port> (default: %u or testnet: %u)"), 8333, 18333) + "\n";
- strUsage += " -proxy=<ip:port> " + _("Connect through SOCKS5 proxy") + "\n";
- strUsage += " -seednode=<ip> " + _("Connect to a node to retrieve peer addresses, and disconnect") + "\n";
- strUsage += " -timeout=<n> " + strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT) + "\n";
+ strUsage += HelpMessageOpt("-txindex", strprintf(_("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)"), 0));
+
+ strUsage += HelpMessageGroup(_("Connection options:"));
+ strUsage += HelpMessageOpt("-addnode=<ip>", _("Add a node to connect to and attempt to keep the connection open"));
+ strUsage += HelpMessageOpt("-banscore=<n>", strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), 100));
+ strUsage += HelpMessageOpt("-bantime=<n>", strprintf(_("Number of seconds to keep misbehaving peers from reconnecting (default: %u)"), 86400));
+ strUsage += HelpMessageOpt("-bind=<addr>", _("Bind to given address and always listen on it. Use [host]:port notation for IPv6"));
+ strUsage += HelpMessageOpt("-connect=<ip>", _("Connect only to the specified node(s)"));
+ strUsage += HelpMessageOpt("-discover", _("Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)"));
+ strUsage += HelpMessageOpt("-dns", _("Allow DNS lookups for -addnode, -seednode and -connect") + " " + _("(default: 1)"));
+ strUsage += HelpMessageOpt("-dnsseed", _("Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)"));
+ strUsage += HelpMessageOpt("-externalip=<ip>", _("Specify your own public address"));
+ strUsage += HelpMessageOpt("-forcednsseed", strprintf(_("Always query for peer addresses via DNS lookup (default: %u)"), 0));
+ strUsage += HelpMessageOpt("-listen", _("Accept connections from outside (default: 1 if no -proxy or -connect)"));
+ strUsage += HelpMessageOpt("-maxconnections=<n>", strprintf(_("Maintain at most <n> connections to peers (default: %u)"), 125));
+ strUsage += HelpMessageOpt("-maxreceivebuffer=<n>", strprintf(_("Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)"), 5000));
+ strUsage += HelpMessageOpt("-maxsendbuffer=<n>", strprintf(_("Maximum per-connection send buffer, <n>*1000 bytes (default: %u)"), 1000));
+ strUsage += HelpMessageOpt("-onion=<ip:port>", strprintf(_("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)"), "-proxy"));
+ strUsage += HelpMessageOpt("-onlynet=<net>", _("Only connect to nodes in network <net> (ipv4, ipv6 or onion)"));
+ strUsage += HelpMessageOpt("-permitbaremultisig", strprintf(_("Relay non-P2SH multisig (default: %u)"), 1));
+ strUsage += HelpMessageOpt("-port=<port>", strprintf(_("Listen for connections on <port> (default: %u or testnet: %u)"), 8333, 18333));
+ strUsage += HelpMessageOpt("-proxy=<ip:port>", _("Connect through SOCKS5 proxy"));
+ strUsage += HelpMessageOpt("-seednode=<ip>", _("Connect to a node to retrieve peer addresses, and disconnect"));
+ strUsage += HelpMessageOpt("-timeout=<n>", strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT));
#ifdef USE_UPNP
#if USE_UPNP
- strUsage += " -upnp " + _("Use UPnP to map the listening port (default: 1 when listening)") + "\n";
+ strUsage += HelpMessageOpt("-upnp", _("Use UPnP to map the listening port (default: 1 when listening)"));
#else
- strUsage += " -upnp " + strprintf(_("Use UPnP to map the listening port (default: %u)"), 0) + "\n";
+ strUsage += HelpMessageOpt("-upnp", strprintf(_("Use UPnP to map the listening port (default: %u)"), 0));
#endif
#endif
- strUsage += " -whitebind=<addr> " + _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6") + "\n";
- strUsage += " -whitelist=<netmask> " + _("Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.") + "\n";
- strUsage += " " + _("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") + "\n";
+ 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"));
+
#ifdef ENABLE_WALLET
- strUsage += "\n" + _("Wallet options:") + "\n";
- strUsage += " -disablewallet " + _("Do not load the wallet and disable wallet RPC calls") + "\n";
- strUsage += " -keypool=<n> " + strprintf(_("Set key pool size to <n> (default: %u)"), 100) + "\n";
+ strUsage += HelpMessageGroup(_("Wallet options:"));
+ strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls"));
+ strUsage += HelpMessageOpt("-keypool=<n>", strprintf(_("Set key pool size to <n> (default: %u)"), 100));
if (GetBoolArg("-help-debug", false))
- strUsage += " -mintxfee=<amt> " + strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)"), FormatMoney(CWallet::minTxFee.GetFeePerK())) + "\n";
- strUsage += " -paytxfee=<amt> " + strprintf(_("Fee (in BTC/kB) to add to transactions you send (default: %s)"), FormatMoney(payTxFee.GetFeePerK())) + "\n";
- strUsage += " -rescan " + _("Rescan the block chain for missing wallet transactions") + " " + _("on startup") + "\n";
- strUsage += " -salvagewallet " + _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup") + "\n";
- strUsage += " -sendfreetransactions " + strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0) + "\n";
- strUsage += " -spendzeroconfchange " + strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1) + "\n";
- strUsage += " -txconfirmtarget=<n> " + strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), 1) + "\n";
- strUsage += " -maxtxfee=<amt> " + strprintf(_("Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)"), FormatMoney(maxTxFee)) + "\n";
- strUsage += " -upgradewallet " + _("Upgrade wallet to latest format") + " " + _("on startup") + "\n";
- strUsage += " -wallet=<file> " + _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat") + "\n";
- strUsage += " -walletnotify=<cmd> " + _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)") + "\n";
- strUsage += " -zapwallettxes=<mode> " + _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") + "\n";
- strUsage += " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)") + "\n";
+ strUsage += HelpMessageOpt("-mintxfee=<amt>", strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)"),
+ FormatMoney(CWallet::minTxFee.GetFeePerK())));
+ strUsage += HelpMessageOpt("-paytxfee=<amt>", strprintf(_("Fee (in BTC/kB) to add to transactions you send (default: %s)"), FormatMoney(payTxFee.GetFeePerK())));
+ strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions") + " " + _("on startup"));
+ strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup"));
+ strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0));
+ strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1));
+ strUsage += HelpMessageOpt("-txconfirmtarget=<n>", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), 1));
+ strUsage += HelpMessageOpt("-maxtxfee=<amt>", strprintf(_("Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)"),
+ FormatMoney(maxTxFee)));
+ strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format") + " " + _("on startup"));
+ strUsage += HelpMessageOpt("-wallet=<file>", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat"));
+ strUsage += HelpMessageOpt("-walletnotify=<cmd>", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)"));
+ strUsage += HelpMessageOpt("-zapwallettxes=<mode>", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") +
+ " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)"));
+
#endif
- strUsage += "\n" + _("Debugging/Testing options:") + "\n";
+ strUsage += HelpMessageGroup(_("Debugging/Testing options:"));
if (GetBoolArg("-help-debug", false))
{
- strUsage += " -checkpoints " + strprintf(_("Only accept block chain matching built-in checkpoints (default: %u)"), 1) + "\n";
- strUsage += " -dblogsize=<n> " + strprintf(_("Flush database activity from memory pool to disk log every <n> megabytes (default: %u)"), 100) + "\n";
- strUsage += " -disablesafemode " + strprintf(_("Disable safemode, override a real safe mode event (default: %u)"), 0) + "\n";
- strUsage += " -testsafemode " + strprintf(_("Force safe mode (default: %u)"), 0) + "\n";
- strUsage += " -dropmessagestest=<n> " + _("Randomly drop 1 of every <n> network messages") + "\n";
- strUsage += " -fuzzmessagestest=<n> " + _("Randomly fuzz 1 of every <n> network messages") + "\n";
- strUsage += " -flushwallet " + strprintf(_("Run a thread to flush wallet periodically (default: %u)"), 1) + "\n";
- strUsage += " -stopafterblockimport " + strprintf(_("Stop running after importing blocks from disk (default: %u)"), 0) + "\n";
+ strUsage += HelpMessageOpt("-checkpoints", strprintf(_("Only accept block chain matching built-in checkpoints (default: %u)"), 1));
+ strUsage += HelpMessageOpt("-dblogsize=<n>", strprintf(_("Flush database activity from memory pool to disk log every <n> megabytes (default: %u)"), 100));
+ strUsage += HelpMessageOpt("-disablesafemode", strprintf(_("Disable safemode, override a real safe mode event (default: %u)"), 0));
+ strUsage += HelpMessageOpt("-testsafemode", strprintf(_("Force safe mode (default: %u)"), 0));
+ strUsage += HelpMessageOpt("-dropmessagestest=<n>", _("Randomly drop 1 of every <n> network messages"));
+ strUsage += HelpMessageOpt("-fuzzmessagestest=<n>", _("Randomly fuzz 1 of every <n> network messages"));
+ strUsage += HelpMessageOpt("-flushwallet", strprintf(_("Run a thread to flush wallet periodically (default: %u)"), 1));
+ strUsage += HelpMessageOpt("-stopafterblockimport", strprintf(_("Stop running after importing blocks from disk (default: %u)"), 0));
}
- strUsage += " -debug=<category> " + strprintf(_("Output debugging information (default: %u, supplying <category> is optional)"), 0) + "\n";
- strUsage += " " + _("If <category> is not supplied, output all debugging information.") + "\n";
- strUsage += " " + _("<category> can be:");
- strUsage += " addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, net"; // Don't translate these and qt below
+ string debugCategories = "addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, net"; // Don't translate these and qt below
if (mode == HMM_BITCOIN_QT)
- strUsage += ", qt";
- strUsage += ".\n";
+ debugCategories += ", qt";
+ strUsage += HelpMessageOpt("-debug=<category>", strprintf(_("Output debugging information (default: %u, supplying <category> is optional)"), 0) + ". " +
+ _("If <category> is not supplied, output all debugging information.") + _("<category> can be:") + " " + debugCategories + ".");
#ifdef ENABLE_WALLET
- strUsage += " -gen " + strprintf(_("Generate coins (default: %u)"), 0) + "\n";
- strUsage += " -genproclimit=<n> " + strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), 1) + "\n";
+ strUsage += HelpMessageOpt("-gen", strprintf(_("Generate coins (default: %u)"), 0));
+ strUsage += HelpMessageOpt("-genproclimit=<n>", strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), 1));
#endif
- strUsage += " -help-debug " + _("Show all debugging options (usage: --help -help-debug)") + "\n";
- strUsage += " -logips " + strprintf(_("Include IP addresses in debug output (default: %u)"), 0) + "\n";
- strUsage += " -logtimestamps " + strprintf(_("Prepend debug output with timestamp (default: %u)"), 1) + "\n";
+ strUsage += HelpMessageOpt("-help-debug", _("Show all debugging options (usage: --help -help-debug)"));
+ strUsage += HelpMessageOpt("-logips", strprintf(_("Include IP addresses in debug output (default: %u)"), 0));
+ strUsage += HelpMessageOpt("-logtimestamps", strprintf(_("Prepend debug output with timestamp (default: %u)"), 1));
if (GetBoolArg("-help-debug", false))
{
- strUsage += " -limitfreerelay=<n> " + strprintf(_("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)"), 15) + "\n";
- strUsage += " -relaypriority " + strprintf(_("Require high priority for relaying free or low-fee transactions (default:%u)"), 1) + "\n";
- strUsage += " -maxsigcachesize=<n> " + strprintf(_("Limit size of signature cache to <n> entries (default: %u)"), 50000) + "\n";
+ strUsage += HelpMessageOpt("-limitfreerelay=<n>", strprintf(_("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)"), 15));
+ strUsage += HelpMessageOpt("-relaypriority", strprintf(_("Require high priority for relaying free or low-fee transactions (default:%u)"), 1));
+ strUsage += HelpMessageOpt("-maxsigcachesize=<n>", strprintf(_("Limit size of signature cache to <n> entries (default: %u)"), 50000));
}
- strUsage += " -minrelaytxfee=<amt> " + strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)"), FormatMoney(::minRelayTxFee.GetFeePerK())) + "\n";
- strUsage += " -printtoconsole " + _("Send trace/debug info to console instead of debug.log file") + "\n";
+ strUsage += HelpMessageOpt("-minrelaytxfee=<amt>", strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)"), FormatMoney(::minRelayTxFee.GetFeePerK())));
+ strUsage += HelpMessageOpt("-printtoconsole", _("Send trace/debug info to console instead of debug.log file"));
if (GetBoolArg("-help-debug", false))
{
- strUsage += " -printpriority " + strprintf(_("Log transaction priority and fee per kB when mining blocks (default: %u)"), 0) + "\n";
- strUsage += " -privdb " + strprintf(_("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)"), 1) + "\n";
- strUsage += " -regtest " + _("Enter regression test mode, which uses a special chain in which blocks can be solved instantly.") + "\n";
- strUsage += " " + _("This is intended for regression testing tools and app development.") + "\n";
- strUsage += " " + _("In this mode -genproclimit controls how many blocks are generated immediately.") + "\n";
+ strUsage += HelpMessageOpt("-printpriority", strprintf(_("Log transaction priority and fee per kB when mining blocks (default: %u)"), 0));
+ strUsage += HelpMessageOpt("-privdb", strprintf(_("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)"), 1));
+ strUsage += HelpMessageOpt("-regtest", _("Enter regression test mode, which uses a special chain in which blocks can be solved instantly.") + " " +
+ _("This is intended for regression testing tools and app development.") + " " +
+ _("In this mode -genproclimit controls how many blocks are generated immediately."));
+ }
+ strUsage += HelpMessageOpt("-shrinkdebugfile", _("Shrink debug.log file on client startup (default: 1 when no -debug)"));
+ strUsage += HelpMessageOpt("-testnet", _("Use the test network"));
+
+ strUsage += HelpMessageGroup(_("Node relay options:"));
+ strUsage += HelpMessageOpt("-datacarrier", strprintf(_("Relay and mine data carrier transactions (default: %u)"), 1));
+ strUsage += HelpMessageOpt("-datacarriersize", strprintf(_("Maximum size of data in data carrier transactions we relay and mine (default: %u)"), MAX_OP_RETURN_RELAY));
+
+ strUsage += HelpMessageGroup(_("Block creation options:"));
+ strUsage += HelpMessageOpt("-blockminsize=<n>", strprintf(_("Set minimum block size in bytes (default: %u)"), 0));
+ strUsage += HelpMessageOpt("-blockmaxsize=<n>", strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE));
+ strUsage += HelpMessageOpt("-blockprioritysize=<n>", strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE));
+
+ strUsage += HelpMessageGroup(_("RPC server options:"));
+ strUsage += HelpMessageOpt("-server", _("Accept command line and JSON-RPC commands"));
+ strUsage += HelpMessageOpt("-rest", strprintf(_("Accept public REST requests (default: %u)"), 0));
+ strUsage += HelpMessageOpt("-rpcbind=<addr>", _("Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)"));
+ strUsage += HelpMessageOpt("-rpcuser=<user>", _("Username for JSON-RPC connections"));
+ strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections"));
+ strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"), 8332, 18332));
+ strUsage += HelpMessageOpt("-rpcallowip=<ip>", _("Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times"));
+ strUsage += HelpMessageOpt("-rpcthreads=<n>", strprintf(_("Set the number of threads to service RPC calls (default: %d)"), 4));
+ strUsage += HelpMessageOpt("-rpckeepalive", strprintf(_("RPC support for HTTP persistent connections (default: %d)"), 1));
+
+ strUsage += HelpMessageGroup(_("RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)"));
+ strUsage += HelpMessageOpt("-rpcssl", _("Use OpenSSL (https) for JSON-RPC connections"));
+ strUsage += HelpMessageOpt("-rpcsslcertificatechainfile=<file.cert>", strprintf(_("Server certificate file (default: %s)"), "server.cert"));
+ strUsage += HelpMessageOpt("-rpcsslprivatekeyfile=<file.pem>", strprintf(_("Server private key (default: %s)"), "server.pem"));
+ strUsage += HelpMessageOpt("-rpcsslciphers=<ciphers>", strprintf(_("Acceptable ciphers (default: %s)"), "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH"));
+
+ if (mode == HMM_BITCOIN_QT)
+ {
+ strUsage += HelpMessageGroup(_("UI Options:"));
+ if (GetBoolArg("-help-debug", false)) {
+ strUsage += HelpMessageOpt("-allowselfsignedrootcertificates", _("Allow self signed root certificates (default: 0)"));
+ }
+ strUsage += HelpMessageOpt("-choosedatadir", _("Choose data directory on startup (default: 0)"));
+ strUsage += HelpMessageOpt("-lang=<lang>", _("Set language, for example \"de_DE\" (default: system locale)"));
+ strUsage += HelpMessageOpt("-min", _("Start minimized"));
+ strUsage += HelpMessageOpt("-rootcertificates=<file>", _("Set SSL root certificates for payment request (default: -system-)"));
+ strUsage += HelpMessageOpt("-splash", _("Show splash screen on startup (default: 1)"));
}
- strUsage += " -shrinkdebugfile " + _("Shrink debug.log file on client startup (default: 1 when no -debug)") + "\n";
- strUsage += " -testnet " + _("Use the test network") + "\n";
-
- strUsage += "\n" + _("Node relay options:") + "\n";
- strUsage += " -datacarrier " + strprintf(_("Relay and mine data carrier transactions (default: %u)"), 1) + "\n";
- strUsage += " -datacarriersize " + strprintf(_("Maximum size of data in data carrier transactions we relay and mine (default: %u)"), MAX_OP_RETURN_RELAY) + "\n";
-
- strUsage += "\n" + _("Block creation options:") + "\n";
- strUsage += " -blockminsize=<n> " + strprintf(_("Set minimum block size in bytes (default: %u)"), 0) + "\n";
- strUsage += " -blockmaxsize=<n> " + strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE) + "\n";
- strUsage += " -blockprioritysize=<n> " + strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE) + "\n";
-
- strUsage += "\n" + _("RPC server options:") + "\n";
- strUsage += " -server " + _("Accept command line and JSON-RPC commands") + "\n";
- strUsage += " -rest " + strprintf(_("Accept public REST requests (default: %u)"), 0) + "\n";
- strUsage += " -rpcbind=<addr> " + _("Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)") + "\n";
- strUsage += " -rpcuser=<user> " + _("Username for JSON-RPC connections") + "\n";
- strUsage += " -rpcpassword=<pw> " + _("Password for JSON-RPC connections") + "\n";
- strUsage += " -rpcport=<port> " + strprintf(_("Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"), 8332, 18332) + "\n";
- strUsage += " -rpcallowip=<ip> " + _("Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times") + "\n";
- strUsage += " -rpcthreads=<n> " + strprintf(_("Set the number of threads to service RPC calls (default: %d)"), 4) + "\n";
- strUsage += " -rpckeepalive " + strprintf(_("RPC support for HTTP persistent connections (default: %d)"), 1) + "\n";
-
- strUsage += "\n" + _("RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n";
- strUsage += " -rpcssl " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n";
- strUsage += " -rpcsslcertificatechainfile=<file.cert> " + strprintf(_("Server certificate file (default: %s)"), "server.cert") + "\n";
- strUsage += " -rpcsslprivatekeyfile=<file.pem> " + strprintf(_("Server private key (default: %s)"), "server.pem") + "\n";
- strUsage += " -rpcsslciphers=<ciphers> " + strprintf(_("Acceptable ciphers (default: %s)"), "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH") + "\n";
return strUsage;
}
diff --git a/src/main.cpp b/src/main.cpp
index b6a61f7da1..6bbb3bc135 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -54,7 +54,6 @@ bool fTxIndex = false;
bool fIsBareMultisigStd = true;
unsigned int nCoinCacheSize = 5000;
-
/** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */
CFeeRate minRelayTxFee = CFeeRate(1000);
@@ -2455,8 +2454,11 @@ bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAdd
}
nLastBlockFile = nFile;
- vinfoBlockFile[nFile].nSize += nAddSize;
vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
+ if (fKnown)
+ vinfoBlockFile[nFile].nSize = std::max(pos.nPos + nAddSize, vinfoBlockFile[nFile].nSize);
+ else
+ vinfoBlockFile[nFile].nSize += nAddSize;
if (!fKnown) {
unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
@@ -2594,8 +2596,7 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
int nHeight = pindexPrev->nHeight+1;
// Check proof of work
- if ((!Params().SkipProofOfWorkCheck()) &&
- (block.nBits != GetNextWorkRequired(pindexPrev, &block)))
+ if ((block.nBits != GetNextWorkRequired(pindexPrev, &block)))
return state.DoS(100, error("%s: incorrect proof of work", __func__),
REJECT_INVALID, "bad-diffbits");
@@ -3085,10 +3086,31 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth
void UnloadBlockIndex()
{
- mapBlockIndex.clear();
+ LOCK(cs_main);
setBlockIndexCandidates.clear();
chainActive.SetTip(NULL);
pindexBestInvalid = NULL;
+ pindexBestHeader = NULL;
+ mempool.clear();
+ mapOrphanTransactions.clear();
+ mapOrphanTransactionsByPrev.clear();
+ nSyncStarted = 0;
+ mapBlocksUnlinked.clear();
+ vinfoBlockFile.clear();
+ nLastBlockFile = 0;
+ nBlockSequenceId = 1;
+ mapBlockSource.clear();
+ mapBlocksInFlight.clear();
+ nQueuedValidatedHeaders = 0;
+ nPreferredDownload = 0;
+ setDirtyBlockIndex.clear();
+ setDirtyFileInfo.clear();
+ mapNodeState.clear();
+
+ BOOST_FOREACH(BlockMap::value_type& entry, mapBlockIndex) {
+ delete entry.second;
+ }
+ mapBlockIndex.clear();
}
bool LoadBlockIndex()
@@ -4021,7 +4043,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
}
- else if (strCommand == "getaddr")
+ // This asymmetric behavior for inbound and outbound connections was introduced
+ // to prevent a fingerprinting attack: an attacker can send specific fake addresses
+ // to users' AddrMan and later request them by sending getaddr messages.
+ // Making users (which are behind NAT and can only make outgoing connections) ignore
+ // getaddr message mitigates the attack.
+ else if ((strCommand == "getaddr") && (pfrom->fInbound))
{
pfrom->vAddrToSend.clear();
vector<CAddress> vAddr = addrman.GetAddr();
@@ -4305,7 +4332,7 @@ bool ProcessMessages(CNode* pfrom)
// Read header
CMessageHeader& hdr = msg.hdr;
- if (!hdr.IsValid())
+ if (!hdr.IsValid(Params().MessageStart()))
{
LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", SanitizeString(hdr.GetCommand()), pfrom->id);
continue;
@@ -4318,8 +4345,7 @@ bool ProcessMessages(CNode* pfrom)
// Checksum
CDataStream& vRecv = msg.vRecv;
uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
- unsigned int nChecksum = 0;
- memcpy(&nChecksum, &hash, sizeof(nChecksum));
+ unsigned int nChecksum = ReadLE32((unsigned char*)&hash);
if (nChecksum != hdr.nChecksum)
{
LogPrintf("ProcessMessages(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
diff --git a/src/net.cpp b/src/net.cpp
index 3c3666615e..0723ee218a 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -14,6 +14,7 @@
#include "clientversion.h"
#include "primitives/transaction.h"
#include "ui_interface.h"
+#include "crypto/common.h"
#ifdef WIN32
#include <string.h>
@@ -509,7 +510,7 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes)
// get current incomplete message, or create a new one
if (vRecvMsg.empty() ||
vRecvMsg.back().complete())
- vRecvMsg.push_back(CNetMessage(SER_NETWORK, nRecvVersion));
+ vRecvMsg.push_back(CNetMessage(Params().MessageStart(), SER_NETWORK, nRecvVersion));
CNetMessage& msg = vRecvMsg.back();
@@ -523,6 +524,11 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes)
if (handled < 0)
return false;
+ if (msg.in_data && msg.hdr.nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH) {
+ LogPrint("net", "Oversized message from peer=%i, disconnecting", GetId());
+ return false;
+ }
+
pch += handled;
nBytes -= handled;
@@ -1970,7 +1976,7 @@ void CNode::BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSen
{
ENTER_CRITICAL_SECTION(cs_vSend);
assert(ssSend.size() == 0);
- ssSend << CMessageHeader(pszCommand, 0);
+ ssSend << CMessageHeader(Params().MessageStart(), pszCommand, 0);
LogPrint("net", "sending: %s ", SanitizeString(pszCommand));
}
@@ -2002,7 +2008,7 @@ void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend)
// Set the size
unsigned int nSize = ssSend.size() - CMessageHeader::HEADER_SIZE;
- memcpy((char*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], &nSize, sizeof(nSize));
+ WriteLE32((uint8_t*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], nSize);
// Set the checksum
uint256 hash = Hash(ssSend.begin() + CMessageHeader::HEADER_SIZE, ssSend.end());
diff --git a/src/net.h b/src/net.h
index e500536cb4..9fc6ce68d0 100644
--- a/src/net.h
+++ b/src/net.h
@@ -46,6 +46,8 @@ static const int TIMEOUT_INTERVAL = 20 * 60;
static const unsigned int MAX_INV_SZ = 50000;
/** The maximum number of new addresses to accumulate before announcing. */
static const unsigned int MAX_ADDR_TO_SEND = 1000;
+/** Maximum length of incoming protocol messages (no message over 2 MiB is currently acceptable). */
+static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = 2 * 1024 * 1024;
/** -listen default */
static const bool DEFAULT_LISTEN = true;
/** -upnp default */
@@ -198,7 +200,7 @@ public:
int64_t nTime; // time (in microseconds) of message receipt.
- CNetMessage(int nTypeIn, int nVersionIn) : hdrbuf(nTypeIn, nVersionIn), vRecv(nTypeIn, nVersionIn) {
+ CNetMessage(const CMessageHeader::MessageStartChars& pchMessageStartIn, int nTypeIn, int nVersionIn) : hdrbuf(nTypeIn, nVersionIn), hdr(pchMessageStartIn), vRecv(nTypeIn, nVersionIn) {
hdrbuf.resize(24);
in_data = false;
nHdrPos = 0;
diff --git a/src/netbase.h b/src/netbase.h
index 5bf13a673f..b42c2dffa4 100644
--- a/src/netbase.h
+++ b/src/netbase.h
@@ -162,7 +162,7 @@ class CService : public CNetAddr
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(FLATDATA(ip));
unsigned short portN = htons(port);
- READWRITE(portN);
+ READWRITE(FLATDATA(portN));
if (ser_action.ForRead())
port = ntohs(portN);
}
diff --git a/src/pow.cpp b/src/pow.cpp
index 6dd5c4c12c..eb899ffc94 100644
--- a/src/pow.cpp
+++ b/src/pow.cpp
@@ -48,8 +48,13 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
pindexFirst = pindexFirst->pprev;
assert(pindexFirst);
+ return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime());
+}
+
+unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime)
+{
// Limit adjustment step
- int64_t nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
+ int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
LogPrintf(" nActualTimespan = %d before bounds\n", nActualTimespan);
if (nActualTimespan < Params().TargetTimespan()/4)
nActualTimespan = Params().TargetTimespan()/4;
@@ -82,9 +87,6 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits)
bool fOverflow;
arith_uint256 bnTarget;
- if (Params().SkipProofOfWorkCheck())
- return true;
-
bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
// Check range
diff --git a/src/pow.h b/src/pow.h
index 3337a30a5e..a5fbba6236 100644
--- a/src/pow.h
+++ b/src/pow.h
@@ -14,6 +14,7 @@ class uint256;
class arith_uint256;
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock);
+unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime);
/** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */
bool CheckProofOfWork(uint256 hash, unsigned int nBits);
diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp
index 3b4a360395..5b9c13d870 100644
--- a/src/primitives/block.cpp
+++ b/src/primitives/block.cpp
@@ -8,10 +8,11 @@
#include "hash.h"
#include "tinyformat.h"
#include "utilstrencodings.h"
+#include "crypto/common.h"
uint256 CBlockHeader::GetHash() const
{
- return Hash(BEGIN(nVersion), END(nNonce));
+ return SerializeHash(*this);
}
uint256 CBlock::BuildMerkleTree(bool* fMutated) const
diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h
index 1b5a47e0da..0ba9affeda 100644
--- a/src/primitives/transaction.h
+++ b/src/primitives/transaction.h
@@ -25,7 +25,8 @@ public:
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(FLATDATA(*this));
+ READWRITE(hash);
+ READWRITE(n);
}
void SetNull() { hash.SetNull(); n = (uint32_t) -1; }
diff --git a/src/protocol.cpp b/src/protocol.cpp
index 74ac706d60..568580a595 100644
--- a/src/protocol.cpp
+++ b/src/protocol.cpp
@@ -5,7 +5,6 @@
#include "protocol.h"
-#include "chainparams.h"
#include "util.h"
#include "utilstrencodings.h"
@@ -21,17 +20,17 @@ static const char* ppszTypeName[] =
"filtered block"
};
-CMessageHeader::CMessageHeader()
+CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn)
{
- memcpy(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE);
+ memcpy(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE);
memset(pchCommand, 0, sizeof(pchCommand));
nMessageSize = -1;
nChecksum = 0;
}
-CMessageHeader::CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn)
+CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn)
{
- memcpy(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE);
+ memcpy(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE);
memset(pchCommand, 0, sizeof(pchCommand));
strncpy(pchCommand, pszCommand, COMMAND_SIZE);
nMessageSize = nMessageSizeIn;
@@ -43,10 +42,10 @@ std::string CMessageHeader::GetCommand() const
return std::string(pchCommand, pchCommand + strnlen(pchCommand, COMMAND_SIZE));
}
-bool CMessageHeader::IsValid() const
+bool CMessageHeader::IsValid(const MessageStartChars& pchMessageStartIn) const
{
// Check start string
- if (memcmp(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0)
+ if (memcmp(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE) != 0)
return false;
// Check the command string for errors
diff --git a/src/protocol.h b/src/protocol.h
index f8394ce52f..e838c0d363 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -29,11 +29,13 @@
class CMessageHeader
{
public:
- CMessageHeader();
- CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn);
+ typedef unsigned char MessageStartChars[MESSAGE_START_SIZE];
+
+ CMessageHeader(const MessageStartChars& pchMessageStartIn);
+ CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn);
std::string GetCommand() const;
- bool IsValid() const;
+ bool IsValid(const MessageStartChars& messageStart) const;
ADD_SERIALIZE_METHODS;
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index a0dcb46e27..1ec968ff2b 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -340,6 +340,7 @@ void BitcoinGUI::createActions()
openAction->setStatusTip(tr("Open a bitcoin: URI or payment request"));
showHelpMessageAction = new QAction(TextColorIcon(":/icons/info"), tr("&Command-line options"), this);
+ showHelpMessageAction->setMenuRole(QAction::NoRole);
showHelpMessageAction->setStatusTip(tr("Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options"));
connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
@@ -435,8 +436,8 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel)
setNumConnections(clientModel->getNumConnections());
connect(clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
- setNumBlocks(clientModel->getNumBlocks());
- connect(clientModel, SIGNAL(numBlocksChanged(int)), this, SLOT(setNumBlocks(int)));
+ setNumBlocks(clientModel->getNumBlocks(), clientModel->getLastBlockDate());
+ connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime)), this, SLOT(setNumBlocks(int,QDateTime)));
// Receive and report messages from client model
connect(clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int)));
@@ -652,7 +653,7 @@ void BitcoinGUI::setNumConnections(int count)
labelConnectionsIcon->setToolTip(tr("%n active connection(s) to Bitcoin network", "", count));
}
-void BitcoinGUI::setNumBlocks(int count)
+void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate)
{
if(!clientModel)
return;
@@ -680,9 +681,8 @@ void BitcoinGUI::setNumBlocks(int count)
QString tooltip;
- QDateTime lastBlockDate = clientModel->getLastBlockDate();
QDateTime currentDate = QDateTime::currentDateTime();
- qint64 secs = lastBlockDate.secsTo(currentDate);
+ qint64 secs = blockDate.secsTo(currentDate);
tooltip = tr("Processed %n blocks of transaction history.", "", count);
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index fd776d63f8..5a289a9046 100644
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -143,8 +143,8 @@ signals:
public slots:
/** Set number of connections shown in the UI */
void setNumConnections(int count);
- /** Set number of blocks shown in the UI */
- void setNumBlocks(int count);
+ /** Set number of blocks and last block date shown in the UI */
+ void setNumBlocks(int count, const QDateTime& blockDate);
/** Notify the user of an event from the core network or transaction handling code.
@param[in] title the message box / notification title
diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp
index 729eb84a18..dc32f81571 100644
--- a/src/qt/clientmodel.cpp
+++ b/src/qt/clientmodel.cpp
@@ -18,7 +18,6 @@
#include <stdint.h>
-#include <QDateTime>
#include <QDebug>
#include <QTimer>
@@ -29,6 +28,7 @@ ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) :
optionsModel(optionsModel),
peerTableModel(0),
cachedNumBlocks(0),
+ cachedBlockDate(QDateTime()),
cachedReindexing(0),
cachedImporting(0),
pollTimer(0)
@@ -79,10 +79,11 @@ quint64 ClientModel::getTotalBytesSent() const
QDateTime ClientModel::getLastBlockDate() const
{
LOCK(cs_main);
+
if (chainActive.Tip())
return QDateTime::fromTime_t(chainActive.Tip()->GetBlockTime());
- else
- return QDateTime::fromTime_t(Params().GenesisBlock().GetBlockTime()); // Genesis block's time of current network
+
+ return QDateTime::fromTime_t(Params().GenesisBlock().GetBlockTime()); // Genesis block's time of current network
}
double ClientModel::getVerificationProgress() const
@@ -97,21 +98,26 @@ void ClientModel::updateTimer()
// periodical polls if the core is holding the locks for a longer time -
// for example, during a wallet rescan.
TRY_LOCK(cs_main, lockMain);
- if(!lockMain)
+ if (!lockMain)
return;
+
// Some quantities (such as number of blocks) change so fast that we don't want to be notified for each change.
// Periodically check and update with a timer.
int newNumBlocks = getNumBlocks();
+ QDateTime newBlockDate = getLastBlockDate();
// check for changed number of blocks we have, number of blocks peers claim to have, reindexing state and importing state
if (cachedNumBlocks != newNumBlocks ||
- cachedReindexing != fReindex || cachedImporting != fImporting)
+ cachedBlockDate != newBlockDate ||
+ cachedReindexing != fReindex ||
+ cachedImporting != fImporting)
{
cachedNumBlocks = newNumBlocks;
+ cachedBlockDate = newBlockDate;
cachedReindexing = fReindex;
cachedImporting = fImporting;
- emit numBlocksChanged(newNumBlocks);
+ emit numBlocksChanged(newNumBlocks, newBlockDate);
}
emit bytesChanged(getTotalBytesRecv(), getTotalBytesSent());
diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h
index 7b74728b26..214701810c 100644
--- a/src/qt/clientmodel.h
+++ b/src/qt/clientmodel.h
@@ -6,6 +6,7 @@
#define BITCOIN_QT_CLIENTMODEL_H
#include <QObject>
+#include <QDateTime>
class AddressTableModel;
class OptionsModel;
@@ -15,7 +16,6 @@ class TransactionTableModel;
class CWallet;
QT_BEGIN_NAMESPACE
-class QDateTime;
class QTimer;
QT_END_NAMESPACE
@@ -73,6 +73,7 @@ private:
PeerTableModel *peerTableModel;
int cachedNumBlocks;
+ QDateTime cachedBlockDate;
bool cachedReindexing;
bool cachedImporting;
@@ -83,7 +84,7 @@ private:
signals:
void numConnectionsChanged(int count);
- void numBlocksChanged(int count);
+ void numBlocksChanged(int count, const QDateTime& blockDate);
void alertsChanged(const QString &warnings);
void bytesChanged(quint64 totalBytesIn, quint64 totalBytesOut);
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index 2a13f43ea4..9db0a75971 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -40,6 +40,7 @@
#if BOOST_FILESYSTEM_VERSION >= 3
#include <boost/filesystem/detail/utf8_codecvt_facet.hpp>
#endif
+#include <boost/scoped_array.hpp>
#include <QAbstractItemView>
#include <QApplication>
@@ -567,12 +568,17 @@ TableViewLastColumnResizingFixer::TableViewLastColumnResizingFixer(QTableView* t
#ifdef WIN32
boost::filesystem::path static StartupShortcutPath()
{
+ if (GetBoolArg("-testnet", false))
+ return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin (testnet).lnk";
+ else if (GetBoolArg("-regtest", false))
+ return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin (regtest).lnk";
+
return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin.lnk";
}
bool GetStartOnSystemStartup()
{
- // check for Bitcoin.lnk
+ // check for Bitcoin*.lnk
return boost::filesystem::exists(StartupShortcutPath());
}
@@ -588,8 +594,8 @@ bool SetStartOnSystemStartup(bool fAutoStart)
// Get a pointer to the IShellLink interface.
IShellLink* psl = NULL;
HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL,
- CLSCTX_INPROC_SERVER, IID_IShellLink,
- reinterpret_cast<void**>(&psl));
+ CLSCTX_INPROC_SERVER, IID_IShellLink,
+ reinterpret_cast<void**>(&psl));
if (SUCCEEDED(hres))
{
@@ -597,20 +603,34 @@ bool SetStartOnSystemStartup(bool fAutoStart)
TCHAR pszExePath[MAX_PATH];
GetModuleFileName(NULL, pszExePath, sizeof(pszExePath));
- TCHAR pszArgs[5] = TEXT("-min");
+ // Start client minimized
+ QString strArgs = "-min";
+ // Set -testnet /-regtest options
+ strArgs += QString::fromStdString(strprintf(" -testnet=%d -regtest=%d", GetBoolArg("-testnet", false), GetBoolArg("-regtest", false)));
+
+#ifdef UNICODE
+ boost::scoped_array<TCHAR> args(new TCHAR[strArgs.length() + 1]);
+ // Convert the QString to TCHAR*
+ strArgs.toWCharArray(args.get());
+ // Add missing '\0'-termination to string
+ args[strArgs.length()] = '\0';
+#endif
// Set the path to the shortcut target
psl->SetPath(pszExePath);
PathRemoveFileSpec(pszExePath);
psl->SetWorkingDirectory(pszExePath);
psl->SetShowCmd(SW_SHOWMINNOACTIVE);
- psl->SetArguments(pszArgs);
+#ifndef UNICODE
+ psl->SetArguments(strArgs.toStdString().c_str());
+#else
+ psl->SetArguments(args.get());
+#endif
// Query IShellLink for the IPersistFile interface for
// saving the shortcut in persistent storage.
IPersistFile* ppf = NULL;
- hres = psl->QueryInterface(IID_IPersistFile,
- reinterpret_cast<void**>(&ppf));
+ hres = psl->QueryInterface(IID_IPersistFile, reinterpret_cast<void**>(&ppf));
if (SUCCEEDED(hres))
{
WCHAR pwsz[MAX_PATH];
@@ -630,11 +650,10 @@ bool SetStartOnSystemStartup(bool fAutoStart)
}
return true;
}
-
#elif defined(Q_OS_LINUX)
// Follow the Desktop Application Autostart Spec:
-// http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html
+// http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html
boost::filesystem::path static GetAutostartDir()
{
@@ -690,8 +709,13 @@ bool SetStartOnSystemStartup(bool fAutoStart)
// Write a bitcoin.desktop file to the autostart directory:
optionFile << "[Desktop Entry]\n";
optionFile << "Type=Application\n";
- optionFile << "Name=Bitcoin\n";
- optionFile << "Exec=" << pszExePath << " -min\n";
+ if (GetBoolArg("-testnet", false))
+ optionFile << "Name=Bitcoin (testnet)\n";
+ else if (GetBoolArg("-regtest", false))
+ optionFile << "Name=Bitcoin (regtest)\n";
+ else
+ optionFile << "Name=Bitcoin\n";
+ optionFile << "Exec=" << pszExePath << strprintf(" -min -testnet=%d -regtest=%d\n", GetBoolArg("-testnet", false), GetBoolArg("-regtest", false));
optionFile << "Terminal=false\n";
optionFile << "Hidden=false\n";
optionFile.close();
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index 9f3991c4c5..ccde44fb29 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -293,8 +293,8 @@ void RPCConsole::setClientModel(ClientModel *model)
setNumConnections(model->getNumConnections());
connect(model, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
- setNumBlocks(model->getNumBlocks());
- connect(model, SIGNAL(numBlocksChanged(int)), this, SLOT(setNumBlocks(int)));
+ setNumBlocks(model->getNumBlocks(), model->getLastBlockDate());
+ connect(model, SIGNAL(numBlocksChanged(int,QDateTime)), this, SLOT(setNumBlocks(int,QDateTime)));
updateTrafficStats(model->getTotalBytesRecv(), model->getTotalBytesSent());
connect(model, SIGNAL(bytesChanged(quint64,quint64)), this, SLOT(updateTrafficStats(quint64, quint64)));
@@ -404,11 +404,10 @@ void RPCConsole::setNumConnections(int count)
ui->numberOfConnections->setText(connections);
}
-void RPCConsole::setNumBlocks(int count)
+void RPCConsole::setNumBlocks(int count, const QDateTime& blockDate)
{
ui->numberOfBlocks->setText(QString::number(count));
- if(clientModel)
- ui->lastBlockTime->setText(clientModel->getLastBlockDate().toString());
+ ui->lastBlockTime->setText(blockDate.toString());
}
void RPCConsole::on_lineEdit_returnPressed()
diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h
index fff5cfbf59..8737be35d1 100644
--- a/src/qt/rpcconsole.h
+++ b/src/qt/rpcconsole.h
@@ -63,8 +63,8 @@ public slots:
void message(int category, const QString &message, bool html = false);
/** Set number of connections shown in the UI */
void setNumConnections(int count);
- /** Set number of blocks shown in the UI */
- void setNumBlocks(int count);
+ /** Set number of blocks and last block date shown in the UI */
+ void setNumBlocks(int count, const QDateTime& blockDate);
/** Go forward or back in history */
void browseHistory(int offset);
/** Scroll console view to end */
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index 5aef2d7539..4f3230a8c9 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -121,7 +121,7 @@ void SendCoinsDialog::setClientModel(ClientModel *clientModel)
this->clientModel = clientModel;
if (clientModel) {
- connect(clientModel, SIGNAL(numBlocksChanged(int)), this, SLOT(updateSmartFeeLabel()));
+ connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime)), this, SLOT(updateSmartFeeLabel()));
}
}
diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp
index 4e7b70efe6..386cf31d73 100644
--- a/src/qt/utilitydialog.cpp
+++ b/src/qt/utilitydialog.cpp
@@ -62,13 +62,17 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) :
ui->helpMessage->setVisible(false);
} else {
setWindowTitle(tr("Command-line options"));
+ QString header = tr("Usage:") + "\n" +
+ " bitcoin-qt [" + tr("command-line options") + "] " + "\n";
QTextCursor cursor(ui->helpMessage->document());
cursor.insertText(version);
cursor.insertBlock();
- cursor.insertText(tr("Usage:") + '\n' +
- " bitcoin-qt [" + tr("command-line options") + "]\n");
-
+ cursor.insertText(header);
cursor.insertBlock();
+
+ QString coreOptions = QString::fromStdString(HelpMessage(HMM_BITCOIN_QT));
+ text = version + "\n" + header + "\n" + coreOptions;
+
QTextTableFormat tf;
tf.setBorderStyle(QTextFrameFormat::BorderStyle_None);
tf.setCellPadding(2);
@@ -76,63 +80,29 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) :
widths << QTextLength(QTextLength::PercentageLength, 35);
widths << QTextLength(QTextLength::PercentageLength, 65);
tf.setColumnWidthConstraints(widths);
- QTextTable *table = cursor.insertTable(2, 2, tf);
- QString coreOptions = QString::fromStdString(HelpMessage(HMM_BITCOIN_QT));
- bool first = true;
QTextCharFormat bold;
bold.setFontWeight(QFont::Bold);
- // note that coreOptions is not translated.
- foreach (const QString &line, coreOptions.split('\n')) {
- if (!first) {
- table->appendRows(1);
+
+ foreach (const QString &line, coreOptions.split("\n")) {
+ if (line.startsWith(" -"))
+ {
+ cursor.currentTable()->appendRows(1);
+ cursor.movePosition(QTextCursor::PreviousCell);
cursor.movePosition(QTextCursor::NextRow);
+ cursor.insertText(line.trimmed());
+ cursor.movePosition(QTextCursor::NextCell);
+ } else if (line.startsWith(" ")) {
+ cursor.insertText(line.trimmed()+' ');
+ } else if (line.size() > 0) {
+ //Title of a group
+ if (cursor.currentTable())
+ cursor.currentTable()->appendRows(1);
+ cursor.movePosition(QTextCursor::Down);
+ cursor.insertText(line.trimmed(), bold);
+ cursor.insertTable(1, 2, tf);
}
- first = false;
-
- if (line.startsWith(" ")) {
- int index = line.indexOf(' ', 3);
- if (index > 0) {
- cursor.insertText(line.left(index).trimmed());
- cursor.movePosition(QTextCursor::NextCell);
- cursor.insertText(line.mid(index).trimmed());
- continue;
- }
- }
- cursor.movePosition(QTextCursor::NextCell, QTextCursor::KeepAnchor);
- table->mergeCells(cursor);
- cursor.insertText(line.trimmed(), bold);
- }
-
- table->appendRows(6);
- cursor.movePosition(QTextCursor::NextRow);
- cursor.insertText(tr("UI options") + ":", bold);
- cursor.movePosition(QTextCursor::NextRow);
- if (GetBoolArg("-help-debug", false)) {
- cursor.insertText("-allowselfsignedrootcertificates");
- cursor.movePosition(QTextCursor::NextCell);
- cursor.insertText(tr("Allow self signed root certificates (default: 0)"));
- cursor.movePosition(QTextCursor::NextCell);
}
- cursor.insertText("-choosedatadir");
- cursor.movePosition(QTextCursor::NextCell);
- cursor.insertText(tr("Choose data directory on startup (default: 0)"));
- cursor.movePosition(QTextCursor::NextCell);
- cursor.insertText("-lang=<lang>");
- cursor.movePosition(QTextCursor::NextCell);
- cursor.insertText(tr("Set language, for example \"de_DE\" (default: system locale)"));
- cursor.movePosition(QTextCursor::NextCell);
- cursor.insertText("-min");
- cursor.movePosition(QTextCursor::NextCell);
- cursor.insertText(tr("Start minimized"));
- cursor.movePosition(QTextCursor::NextCell);
- cursor.insertText("-rootcertificates=<file>");
- cursor.movePosition(QTextCursor::NextCell);
- cursor.insertText(tr("Set SSL root certificates for payment request (default: -system-)"));
- cursor.movePosition(QTextCursor::NextCell);
- cursor.insertText("-splash");
- cursor.movePosition(QTextCursor::NextCell);
- cursor.insertText(tr("Show splash screen on startup (default: 1)"));
ui->helpMessage->moveCursor(QTextCursor::Start);
ui->scrollArea->setVisible(false);
diff --git a/src/script/script.h b/src/script/script.h
index 8b36aa2f50..ed456f5c5a 100644
--- a/src/script/script.h
+++ b/src/script/script.h
@@ -14,6 +14,7 @@
#include <string.h>
#include <string>
#include <vector>
+#include "crypto/common.h"
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520; // bytes
@@ -416,14 +417,16 @@ public:
else if (b.size() <= 0xffff)
{
insert(end(), OP_PUSHDATA2);
- unsigned short nSize = b.size();
- insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize));
+ uint8_t data[2];
+ WriteLE16(data, b.size());
+ insert(end(), data, data + sizeof(data));
}
else
{
insert(end(), OP_PUSHDATA4);
- unsigned int nSize = b.size();
- insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize));
+ uint8_t data[4];
+ WriteLE32(data, b.size());
+ insert(end(), data, data + sizeof(data));
}
insert(end(), b.begin(), b.end());
return *this;
@@ -496,15 +499,14 @@ public:
{
if (end() - pc < 2)
return false;
- nSize = 0;
- memcpy(&nSize, &pc[0], 2);
+ nSize = ReadLE16(&pc[0]);
pc += 2;
}
else if (opcode == OP_PUSHDATA4)
{
if (end() - pc < 4)
return false;
- memcpy(&nSize, &pc[0], 4);
+ nSize = ReadLE32(&pc[0]);
pc += 4;
}
if (end() - pc < 0 || (unsigned int)(end() - pc) < nSize)
diff --git a/src/serialize.h b/src/serialize.h
index a62760a793..741f78f8b4 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -18,6 +18,8 @@
#include <utility>
#include <vector>
+#include "compat/endian.h"
+
class CScript;
static const unsigned int MAX_SIZE = 0x02000000;
@@ -71,6 +73,79 @@ inline const T* end_ptr(const std::vector<T,TAl>& v)
return v.empty() ? NULL : (&v[0] + v.size());
}
+/*
+ * Lowest-level serialization and conversion.
+ * @note Sizes of these types are verified in the tests
+ */
+template<typename Stream> inline void ser_writedata8(Stream &s, uint8_t obj)
+{
+ s.write((char*)&obj, 1);
+}
+template<typename Stream> inline void ser_writedata16(Stream &s, uint16_t obj)
+{
+ obj = htole16(obj);
+ s.write((char*)&obj, 2);
+}
+template<typename Stream> inline void ser_writedata32(Stream &s, uint32_t obj)
+{
+ obj = htole32(obj);
+ s.write((char*)&obj, 4);
+}
+template<typename Stream> inline void ser_writedata64(Stream &s, uint64_t obj)
+{
+ obj = htole64(obj);
+ s.write((char*)&obj, 8);
+}
+template<typename Stream> inline uint8_t ser_readdata8(Stream &s)
+{
+ uint8_t obj;
+ s.read((char*)&obj, 1);
+ return obj;
+}
+template<typename Stream> inline uint16_t ser_readdata16(Stream &s)
+{
+ uint16_t obj;
+ s.read((char*)&obj, 2);
+ return le16toh(obj);
+}
+template<typename Stream> inline uint32_t ser_readdata32(Stream &s)
+{
+ uint32_t obj;
+ s.read((char*)&obj, 4);
+ return le32toh(obj);
+}
+template<typename Stream> inline uint64_t ser_readdata64(Stream &s)
+{
+ uint64_t obj;
+ s.read((char*)&obj, 8);
+ return le64toh(obj);
+}
+inline uint64_t ser_double_to_uint64(double x)
+{
+ union { double x; uint64_t y; } tmp;
+ tmp.x = x;
+ return tmp.y;
+}
+inline uint32_t ser_float_to_uint32(float x)
+{
+ union { float x; uint32_t y; } tmp;
+ tmp.x = x;
+ return tmp.y;
+}
+inline double ser_uint64_to_double(uint64_t y)
+{
+ union { double x; uint64_t y; } tmp;
+ tmp.y = y;
+ return tmp.x;
+}
+inline float ser_uint32_to_float(uint32_t y)
+{
+ union { float x; uint32_t y; } tmp;
+ tmp.y = y;
+ return tmp.x;
+}
+
+
/////////////////////////////////////////////////////////////////
//
// Templates for serializing to anything that looks like a stream,
@@ -108,59 +183,48 @@ enum
SerializationOp(s, CSerActionUnserialize(), nType, nVersion); \
}
-
-
/*
* Basic Types
*/
-#define WRITEDATA(s, obj) s.write((char*)&(obj), sizeof(obj))
-#define READDATA(s, obj) s.read((char*)&(obj), sizeof(obj))
-
-inline unsigned int GetSerializeSize(char a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(signed char a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(unsigned char a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(signed short a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(unsigned short a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(signed int a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(unsigned int a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(signed long a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(unsigned long a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(signed long long a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(unsigned long long a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(float a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(double a, int, int=0) { return sizeof(a); }
-
-template<typename Stream> inline void Serialize(Stream& s, char a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, signed char a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, unsigned char a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, signed short a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, unsigned short a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, signed int a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, unsigned int a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, signed long a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, unsigned long a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, signed long long a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, unsigned long long a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, float a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, double a, int, int=0) { WRITEDATA(s, a); }
-
-template<typename Stream> inline void Unserialize(Stream& s, char& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, signed char& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, unsigned char& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, signed short& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, unsigned short& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, signed int& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, unsigned int& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, signed long& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, unsigned long& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, signed long long& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, unsigned long long& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, float& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, double& a, int, int=0) { READDATA(s, a); }
+inline unsigned int GetSerializeSize(char a, int, int=0) { return 1; }
+inline unsigned int GetSerializeSize(int8_t a, int, int=0) { return 1; }
+inline unsigned int GetSerializeSize(uint8_t a, int, int=0) { return 1; }
+inline unsigned int GetSerializeSize(int16_t a, int, int=0) { return 2; }
+inline unsigned int GetSerializeSize(uint16_t a, int, int=0) { return 2; }
+inline unsigned int GetSerializeSize(int32_t a, int, int=0) { return 4; }
+inline unsigned int GetSerializeSize(uint32_t a, int, int=0) { return 4; }
+inline unsigned int GetSerializeSize(int64_t a, int, int=0) { return 8; }
+inline unsigned int GetSerializeSize(uint64_t a, int, int=0) { return 8; }
+inline unsigned int GetSerializeSize(float a, int, int=0) { return 4; }
+inline unsigned int GetSerializeSize(double a, int, int=0) { return 8; }
+
+template<typename Stream> inline void Serialize(Stream& s, char a, int, int=0) { ser_writedata8(s, a); } // TODO Get rid of bare char
+template<typename Stream> inline void Serialize(Stream& s, int8_t a, int, int=0) { ser_writedata8(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, uint8_t a, int, int=0) { ser_writedata8(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, int16_t a, int, int=0) { ser_writedata16(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, uint16_t a, int, int=0) { ser_writedata16(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, int32_t a, int, int=0) { ser_writedata32(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, uint32_t a, int, int=0) { ser_writedata32(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, int64_t a, int, int=0) { ser_writedata64(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, uint64_t a, int, int=0) { ser_writedata64(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, float a, int, int=0) { ser_writedata32(s, ser_float_to_uint32(a)); }
+template<typename Stream> inline void Serialize(Stream& s, double a, int, int=0) { ser_writedata64(s, ser_double_to_uint64(a)); }
+
+template<typename Stream> inline void Unserialize(Stream& s, char& a, int, int=0) { a = ser_readdata8(s); } // TODO Get rid of bare char
+template<typename Stream> inline void Unserialize(Stream& s, int8_t& a, int, int=0) { a = ser_readdata8(s); }
+template<typename Stream> inline void Unserialize(Stream& s, uint8_t& a, int, int=0) { a = ser_readdata8(s); }
+template<typename Stream> inline void Unserialize(Stream& s, int16_t& a, int, int=0) { a = ser_readdata16(s); }
+template<typename Stream> inline void Unserialize(Stream& s, uint16_t& a, int, int=0) { a = ser_readdata16(s); }
+template<typename Stream> inline void Unserialize(Stream& s, int32_t& a, int, int=0) { a = ser_readdata32(s); }
+template<typename Stream> inline void Unserialize(Stream& s, uint32_t& a, int, int=0) { a = ser_readdata32(s); }
+template<typename Stream> inline void Unserialize(Stream& s, int64_t& a, int, int=0) { a = ser_readdata64(s); }
+template<typename Stream> inline void Unserialize(Stream& s, uint64_t& a, int, int=0) { a = ser_readdata64(s); }
+template<typename Stream> inline void Unserialize(Stream& s, float& a, int, int=0) { a = ser_uint32_to_float(ser_readdata32(s)); }
+template<typename Stream> inline void Unserialize(Stream& s, double& a, int, int=0) { a = ser_uint64_to_double(ser_readdata64(s)); }
inline unsigned int GetSerializeSize(bool a, int, int=0) { return sizeof(char); }
-template<typename Stream> inline void Serialize(Stream& s, bool a, int, int=0) { char f=a; WRITEDATA(s, f); }
-template<typename Stream> inline void Unserialize(Stream& s, bool& a, int, int=0) { char f; READDATA(s, f); a=f; }
+template<typename Stream> inline void Serialize(Stream& s, bool a, int, int=0) { char f=a; ser_writedata8(s, f); }
+template<typename Stream> inline void Unserialize(Stream& s, bool& a, int, int=0) { char f=ser_readdata8(s); a=f; }
@@ -187,29 +251,22 @@ void WriteCompactSize(Stream& os, uint64_t nSize)
{
if (nSize < 253)
{
- unsigned char chSize = nSize;
- WRITEDATA(os, chSize);
+ ser_writedata8(os, nSize);
}
else if (nSize <= std::numeric_limits<unsigned short>::max())
{
- unsigned char chSize = 253;
- unsigned short xSize = nSize;
- WRITEDATA(os, chSize);
- WRITEDATA(os, xSize);
+ ser_writedata8(os, 253);
+ ser_writedata16(os, nSize);
}
else if (nSize <= std::numeric_limits<unsigned int>::max())
{
- unsigned char chSize = 254;
- unsigned int xSize = nSize;
- WRITEDATA(os, chSize);
- WRITEDATA(os, xSize);
+ ser_writedata8(os, 254);
+ ser_writedata32(os, nSize);
}
else
{
- unsigned char chSize = 255;
- uint64_t xSize = nSize;
- WRITEDATA(os, chSize);
- WRITEDATA(os, xSize);
+ ser_writedata8(os, 255);
+ ser_writedata64(os, nSize);
}
return;
}
@@ -217,8 +274,7 @@ void WriteCompactSize(Stream& os, uint64_t nSize)
template<typename Stream>
uint64_t ReadCompactSize(Stream& is)
{
- unsigned char chSize;
- READDATA(is, chSize);
+ uint8_t chSize = ser_readdata8(is);
uint64_t nSizeRet = 0;
if (chSize < 253)
{
@@ -226,25 +282,19 @@ uint64_t ReadCompactSize(Stream& is)
}
else if (chSize == 253)
{
- unsigned short xSize;
- READDATA(is, xSize);
- nSizeRet = xSize;
+ nSizeRet = ser_readdata16(is);
if (nSizeRet < 253)
throw std::ios_base::failure("non-canonical ReadCompactSize()");
}
else if (chSize == 254)
{
- unsigned int xSize;
- READDATA(is, xSize);
- nSizeRet = xSize;
+ nSizeRet = ser_readdata32(is);
if (nSizeRet < 0x10000u)
throw std::ios_base::failure("non-canonical ReadCompactSize()");
}
else
{
- uint64_t xSize;
- READDATA(is, xSize);
- nSizeRet = xSize;
+ nSizeRet = ser_readdata64(is);
if (nSizeRet < 0x100000000ULL)
throw std::ios_base::failure("non-canonical ReadCompactSize()");
}
@@ -303,7 +353,7 @@ void WriteVarInt(Stream& os, I n)
len++;
}
do {
- WRITEDATA(os, tmp[len]);
+ ser_writedata8(os, tmp[len]);
} while(len--);
}
@@ -312,8 +362,7 @@ I ReadVarInt(Stream& is)
{
I n = 0;
while(true) {
- unsigned char chData;
- READDATA(is, chData);
+ unsigned char chData = ser_readdata8(is);
n = (n << 7) | (chData & 0x7F);
if (chData & 0x80)
n++;
diff --git a/src/test/Checkpoints_tests.cpp b/src/test/Checkpoints_tests.cpp
index a9b6cd44a8..c3125d76dc 100644
--- a/src/test/Checkpoints_tests.cpp
+++ b/src/test/Checkpoints_tests.cpp
@@ -9,12 +9,13 @@
#include "checkpoints.h"
#include "uint256.h"
+#include "test/test_bitcoin.h"
#include <boost/test/unit_test.hpp>
using namespace std;
-BOOST_AUTO_TEST_SUITE(Checkpoints_tests)
+BOOST_FIXTURE_TEST_SUITE(Checkpoints_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(sanity)
{
diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp
index 9407511ecb..bf25548755 100644
--- a/src/test/DoS_tests.cpp
+++ b/src/test/DoS_tests.cpp
@@ -16,6 +16,8 @@
#include "serialize.h"
#include "util.h"
+#include "test/test_bitcoin.h"
+
#include <stdint.h>
#include <boost/assign/list_of.hpp> // for 'map_list_of()'
@@ -41,7 +43,7 @@ CService ip(uint32_t i)
return CService(CNetAddr(s), Params().GetDefaultPort());
}
-BOOST_AUTO_TEST_SUITE(DoS_tests)
+BOOST_FIXTURE_TEST_SUITE(DoS_tests, TestingSetup)
BOOST_AUTO_TEST_CASE(DoS_banning)
{
diff --git a/src/test/accounting_tests.cpp b/src/test/accounting_tests.cpp
index da07b8c7a6..36499f01a7 100644
--- a/src/test/accounting_tests.cpp
+++ b/src/test/accounting_tests.cpp
@@ -5,6 +5,8 @@
#include "wallet.h"
#include "walletdb.h"
+#include "test/test_bitcoin.h"
+
#include <stdint.h>
#include <boost/foreach.hpp>
@@ -12,7 +14,7 @@
extern CWallet* pwalletMain;
-BOOST_AUTO_TEST_SUITE(accounting_tests)
+BOOST_FIXTURE_TEST_SUITE(accounting_tests, TestingSetup)
static void
GetResults(CWalletDB& walletdb, std::map<CAmount, CAccountingEntry>& results)
diff --git a/src/test/alert_tests.cpp b/src/test/alert_tests.cpp
index efc9211717..5e1f5f0294 100644
--- a/src/test/alert_tests.cpp
+++ b/src/test/alert_tests.cpp
@@ -15,6 +15,8 @@
#include "util.h"
#include "utilstrencodings.h"
+#include "test/test_bitcoin.h"
+
#include <fstream>
#include <boost/filesystem/operations.hpp>
@@ -78,7 +80,7 @@
}
#endif
-struct ReadAlerts
+struct ReadAlerts : public TestingSetup
{
ReadAlerts()
{
diff --git a/src/test/allocator_tests.cpp b/src/test/allocator_tests.cpp
index 991b4ac099..d4df7b5415 100644
--- a/src/test/allocator_tests.cpp
+++ b/src/test/allocator_tests.cpp
@@ -5,10 +5,11 @@
#include "util.h"
#include "allocators.h"
+#include "test/test_bitcoin.h"
#include <boost/test/unit_test.hpp>
-BOOST_AUTO_TEST_SUITE(allocator_tests)
+BOOST_FIXTURE_TEST_SUITE(allocator_tests, BasicTestingSetup)
// Dummy memory page locker for platform independent tests
static const void *last_lock_addr, *last_unlock_addr;
diff --git a/src/test/arith_uint256_tests.cpp b/src/test/arith_uint256_tests.cpp
index 565b02ae64..17d6bed6d2 100644
--- a/src/test/arith_uint256_tests.cpp
+++ b/src/test/arith_uint256_tests.cpp
@@ -12,8 +12,9 @@
#include "arith_uint256.h"
#include <string>
#include "version.h"
+#include "test/test_bitcoin.h"
-BOOST_AUTO_TEST_SUITE(arith_uint256_tests)
+BOOST_FIXTURE_TEST_SUITE(arith_uint256_tests, BasicTestingSetup)
/// Convert vector to arith_uint256, via uint256 blob
inline arith_uint256 arith_uint256V(const std::vector<unsigned char>& vch)
diff --git a/src/test/base32_tests.cpp b/src/test/base32_tests.cpp
index 5d20a90ad0..8ec8861425 100644
--- a/src/test/base32_tests.cpp
+++ b/src/test/base32_tests.cpp
@@ -3,10 +3,11 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "utilstrencodings.h"
+#include "test/test_bitcoin.h"
#include <boost/test/unit_test.hpp>
-BOOST_AUTO_TEST_SUITE(base32_tests)
+BOOST_FIXTURE_TEST_SUITE(base32_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(base32_testvectors)
{
diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp
index e7d0281881..f07dd7a7db 100644
--- a/src/test/base58_tests.cpp
+++ b/src/test/base58_tests.cpp
@@ -13,6 +13,7 @@
#include "uint256.h"
#include "util.h"
#include "utilstrencodings.h"
+#include "test/test_bitcoin.h"
#include <boost/foreach.hpp>
#include <boost/test/unit_test.hpp>
@@ -23,7 +24,7 @@
using namespace json_spirit;
extern Array read_json(const std::string& jsondata);
-BOOST_AUTO_TEST_SUITE(base58_tests)
+BOOST_FIXTURE_TEST_SUITE(base58_tests, BasicTestingSetup)
// Goal: test low-level base58 encoding functionality
BOOST_AUTO_TEST_CASE(base58_EncodeBase58)
@@ -127,6 +128,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse)
std::vector<unsigned char> result;
CBitcoinSecret secret;
CBitcoinAddress addr;
+ SelectParams(CBaseChainParams::MAIN);
BOOST_FOREACH(Value& tv, tests)
{
@@ -176,7 +178,6 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse)
BOOST_CHECK_MESSAGE(!secret.IsValid(), "IsValid pubkey as privkey:" + strTest);
}
}
- SelectParams(CBaseChainParams::UNITTEST);
}
// Goal: check that generated keys match test vectors
@@ -244,7 +245,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen)
CTxDestination nodest = CNoDestination();
BOOST_CHECK(!dummyAddr.Set(nodest));
- SelectParams(CBaseChainParams::UNITTEST);
+ SelectParams(CBaseChainParams::MAIN);
}
// Goal: check that base58 parsing code is robust against a variety of corrupted data
diff --git a/src/test/base64_tests.cpp b/src/test/base64_tests.cpp
index 9e6cb342cc..54c081b0ef 100644
--- a/src/test/base64_tests.cpp
+++ b/src/test/base64_tests.cpp
@@ -3,10 +3,11 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "utilstrencodings.h"
+#include "test/test_bitcoin.h"
#include <boost/test/unit_test.hpp>
-BOOST_AUTO_TEST_SUITE(base64_tests)
+BOOST_FIXTURE_TEST_SUITE(base64_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(base64_testvectors)
{
diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp
index 3d28e06ffc..d738851c1f 100644
--- a/src/test/bip32_tests.cpp
+++ b/src/test/bip32_tests.cpp
@@ -8,6 +8,7 @@
#include "key.h"
#include "uint256.h"
#include "util.h"
+#include "test/test_bitcoin.h"
#include <string>
#include <vector>
@@ -107,7 +108,7 @@ void RunTest(const TestVector &test) {
}
}
-BOOST_AUTO_TEST_SUITE(bip32_tests)
+BOOST_FIXTURE_TEST_SUITE(bip32_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(bip32_test1) {
RunTest(test1);
diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp
index 64d9909b98..73a146f05c 100644
--- a/src/test/bloom_tests.cpp
+++ b/src/test/bloom_tests.cpp
@@ -13,6 +13,7 @@
#include "uint256.h"
#include "util.h"
#include "utilstrencodings.h"
+#include "test/test_bitcoin.h"
#include <vector>
@@ -21,7 +22,7 @@
using namespace std;
-BOOST_AUTO_TEST_SUITE(bloom_tests)
+BOOST_FIXTURE_TEST_SUITE(bloom_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize)
{
diff --git a/src/test/checkblock_tests.cpp b/src/test/checkblock_tests.cpp
index a4121caa8b..7abfad151e 100644
--- a/src/test/checkblock_tests.cpp
+++ b/src/test/checkblock_tests.cpp
@@ -11,6 +11,7 @@
#include "clientversion.h"
#include "main.h"
#include "utiltime.h"
+#include "test/test_bitcoin.h"
#include <cstdio>
@@ -19,7 +20,7 @@
#include <boost/test/unit_test.hpp>
-BOOST_AUTO_TEST_SUITE(CheckBlock_tests)
+BOOST_FIXTURE_TEST_SUITE(CheckBlock_tests, BasicTestingSetup)
bool read_block(const std::string& filename, CBlock& block)
{
diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp
index 3ecd301bc7..2e2cc2214b 100644
--- a/src/test/coins_tests.cpp
+++ b/src/test/coins_tests.cpp
@@ -5,6 +5,7 @@
#include "coins.h"
#include "random.h"
#include "uint256.h"
+#include "test/test_bitcoin.h"
#include <vector>
#include <map>
@@ -60,7 +61,7 @@ public:
};
}
-BOOST_AUTO_TEST_SUITE(coins_tests)
+BOOST_FIXTURE_TEST_SUITE(coins_tests, BasicTestingSetup)
static const unsigned int NUM_SIMULATION_ITERATIONS = 40000;
diff --git a/src/test/compress_tests.cpp b/src/test/compress_tests.cpp
index b4e4f2046f..376ae93681 100644
--- a/src/test/compress_tests.cpp
+++ b/src/test/compress_tests.cpp
@@ -4,6 +4,7 @@
#include "compressor.h"
#include "util.h"
+#include "test/test_bitcoin.h"
#include <stdint.h>
@@ -21,7 +22,7 @@
// amounts 50 .. 21000000
#define NUM_MULTIPLES_50BTC 420000
-BOOST_AUTO_TEST_SUITE(compress_tests)
+BOOST_FIXTURE_TEST_SUITE(compress_tests, BasicTestingSetup)
bool static TestEncode(uint64_t in) {
return in == CTxOutCompressor::DecompressAmount(CTxOutCompressor::CompressAmount(in));
diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp
index d5e595cd8a..aeb2a5caa3 100644
--- a/src/test/crypto_tests.cpp
+++ b/src/test/crypto_tests.cpp
@@ -10,13 +10,14 @@
#include "crypto/hmac_sha512.h"
#include "random.h"
#include "utilstrencodings.h"
+#include "test/test_bitcoin.h"
#include <vector>
#include <boost/assign/list_of.hpp>
#include <boost/test/unit_test.hpp>
-BOOST_AUTO_TEST_SUITE(crypto_tests)
+BOOST_FIXTURE_TEST_SUITE(crypto_tests, BasicTestingSetup)
template<typename Hasher, typename In, typename Out>
void TestVector(const Hasher &h, const In &in, const Out &out) {
diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp
index 5fb0f4ccdd..a0c5592a95 100644
--- a/src/test/getarg_tests.cpp
+++ b/src/test/getarg_tests.cpp
@@ -3,6 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "util.h"
+#include "test/test_bitcoin.h"
#include <string>
#include <vector>
@@ -11,7 +12,7 @@
#include <boost/foreach.hpp>
#include <boost/test/unit_test.hpp>
-BOOST_AUTO_TEST_SUITE(getarg_tests)
+BOOST_FIXTURE_TEST_SUITE(getarg_tests, BasicTestingSetup)
static void ResetArgs(const std::string& strArg)
{
diff --git a/src/test/hash_tests.cpp b/src/test/hash_tests.cpp
index f1ad25e6ee..e5d2e5a439 100644
--- a/src/test/hash_tests.cpp
+++ b/src/test/hash_tests.cpp
@@ -4,6 +4,7 @@
#include "hash.h"
#include "utilstrencodings.h"
+#include "test/test_bitcoin.h"
#include <vector>
@@ -11,7 +12,7 @@
using namespace std;
-BOOST_AUTO_TEST_SUITE(hash_tests)
+BOOST_FIXTURE_TEST_SUITE(hash_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(murmurhash3)
{
diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp
index 1333aba471..13ca949469 100644
--- a/src/test/key_tests.cpp
+++ b/src/test/key_tests.cpp
@@ -9,6 +9,7 @@
#include "uint256.h"
#include "util.h"
#include "utilstrencodings.h"
+#include "test/test_bitcoin.h"
#include <string>
#include <vector>
@@ -58,7 +59,7 @@ void dumpKeyInfo(uint256 privkey)
#endif
-BOOST_AUTO_TEST_SUITE(key_tests)
+BOOST_FIXTURE_TEST_SUITE(key_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(key_test1)
{
diff --git a/src/test/main_tests.cpp b/src/test/main_tests.cpp
index 5e968c26ff..9ec533bcca 100644
--- a/src/test/main_tests.cpp
+++ b/src/test/main_tests.cpp
@@ -5,9 +5,11 @@
#include "primitives/transaction.h"
#include "main.h"
+#include "test/test_bitcoin.h"
+
#include <boost/test/unit_test.hpp>
-BOOST_AUTO_TEST_SUITE(main_tests)
+BOOST_FIXTURE_TEST_SUITE(main_tests, TestingSetup)
BOOST_AUTO_TEST_CASE(subsidy_limit_test)
{
diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp
index 44c57a8eaf..6ab9cb8a44 100644
--- a/src/test/miner_tests.cpp
+++ b/src/test/miner_tests.cpp
@@ -8,9 +8,11 @@
#include "uint256.h"
#include "util.h"
+#include "test/test_bitcoin.h"
+
#include <boost/test/unit_test.hpp>
-BOOST_AUTO_TEST_SUITE(miner_tests)
+BOOST_FIXTURE_TEST_SUITE(miner_tests, TestingSetup)
static
struct {
diff --git a/src/test/mruset_tests.cpp b/src/test/mruset_tests.cpp
index 813ec9b8b2..bd4e9c1d38 100644
--- a/src/test/mruset_tests.cpp
+++ b/src/test/mruset_tests.cpp
@@ -6,6 +6,7 @@
#include "random.h"
#include "util.h"
+#include "test/test_bitcoin.h"
#include <set>
@@ -34,7 +35,7 @@ public:
}
};
-BOOST_AUTO_TEST_SUITE(mruset_tests)
+BOOST_FIXTURE_TEST_SUITE(mruset_tests, BasicTestingSetup)
// Test that an mruset behaves like a set, as long as no more than MAX_SIZE elements are in it
BOOST_AUTO_TEST_CASE(mruset_like_set)
diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp
index 2168a5fef1..054bc3b37b 100644
--- a/src/test/multisig_tests.cpp
+++ b/src/test/multisig_tests.cpp
@@ -10,6 +10,7 @@
#include "script/interpreter.h"
#include "script/sign.h"
#include "uint256.h"
+#include "test/test_bitcoin.h"
#ifdef ENABLE_WALLET
#include "wallet_ismine.h"
@@ -22,7 +23,7 @@ using namespace std;
typedef vector<unsigned char> valtype;
-BOOST_AUTO_TEST_SUITE(multisig_tests)
+BOOST_FIXTURE_TEST_SUITE(multisig_tests, BasicTestingSetup)
CScript
sign_multisig(CScript scriptPubKey, vector<CKey> keys, CTransaction transaction, int whichIn)
diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp
index 9361459949..cb357d295c 100644
--- a/src/test/netbase_tests.cpp
+++ b/src/test/netbase_tests.cpp
@@ -3,6 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "netbase.h"
+#include "test/test_bitcoin.h"
#include <string>
@@ -10,7 +11,7 @@
using namespace std;
-BOOST_AUTO_TEST_SUITE(netbase_tests)
+BOOST_FIXTURE_TEST_SUITE(netbase_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(netbase_networks)
{
diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp
index 4406b08e56..f6d06d6805 100644
--- a/src/test/pmt_tests.cpp
+++ b/src/test/pmt_tests.cpp
@@ -9,6 +9,7 @@
#include "arith_uint256.h"
#include "version.h"
#include "random.h"
+#include "test/test_bitcoin.h"
#include <vector>
@@ -28,7 +29,7 @@ public:
}
};
-BOOST_AUTO_TEST_SUITE(pmt_tests)
+BOOST_FIXTURE_TEST_SUITE(pmt_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(pmt_test1)
{
diff --git a/src/test/pow_tests.cpp b/src/test/pow_tests.cpp
new file mode 100644
index 0000000000..7b197c527d
--- /dev/null
+++ b/src/test/pow_tests.cpp
@@ -0,0 +1,67 @@
+// Copyright (c) 2015 The Bitcoin Core developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "main.h"
+#include "pow.h"
+#include "util.h"
+#include "test/test_bitcoin.h"
+
+#include <boost/test/unit_test.hpp>
+
+using namespace std;
+
+BOOST_FIXTURE_TEST_SUITE(pow_tests, BasicTestingSetup)
+
+/* Test calculation of next difficulty target with no constraints applying */
+BOOST_AUTO_TEST_CASE(get_next_work)
+{
+ SelectParams(CBaseChainParams::MAIN);
+
+ int64_t nLastRetargetTime = 1261130161; // Block #30240
+ CBlockIndex pindexLast;
+ pindexLast.nHeight = 32255;
+ pindexLast.nTime = 1262152739; // Block #32255
+ pindexLast.nBits = 0x1d00ffff;
+ BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime), 0x1d00d86a);
+}
+
+/* Test the constraint on the upper bound for next work */
+BOOST_AUTO_TEST_CASE(get_next_work_pow_limit)
+{
+ SelectParams(CBaseChainParams::MAIN);
+
+ int64_t nLastRetargetTime = 1231006505; // Block #0
+ CBlockIndex pindexLast;
+ pindexLast.nHeight = 2015;
+ pindexLast.nTime = 1233061996; // Block #2015
+ pindexLast.nBits = 0x1d00ffff;
+ BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime), 0x1d00ffff);
+}
+
+/* Test the constraint on the lower bound for actual time taken */
+BOOST_AUTO_TEST_CASE(get_next_work_lower_limit_actual)
+{
+ SelectParams(CBaseChainParams::MAIN);
+
+ int64_t nLastRetargetTime = 1279008237; // Block #66528
+ CBlockIndex pindexLast;
+ pindexLast.nHeight = 68543;
+ pindexLast.nTime = 1279297671; // Block #68543
+ pindexLast.nBits = 0x1c05a3f4;
+ BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime), 0x1c0168fd);
+}
+
+/* Test the constraint on the upper bound for actual time taken */
+BOOST_AUTO_TEST_CASE(get_next_work_upper_limit_actual)
+{
+ SelectParams(CBaseChainParams::MAIN);
+ int64_t nLastRetargetTime = 1263163443; // NOTE: Not an actual block time
+ CBlockIndex pindexLast;
+ pindexLast.nHeight = 46367;
+ pindexLast.nTime = 1269211443; // Block #46367
+ pindexLast.nBits = 0x1c387f6f;
+ BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime), 0x1d00e1fd);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp
index 1c6963001f..45cb551d04 100644
--- a/src/test/rpc_tests.cpp
+++ b/src/test/rpc_tests.cpp
@@ -8,6 +8,8 @@
#include "base58.h"
#include "netbase.h"
+#include "test/test_bitcoin.h"
+
#include <boost/algorithm/string.hpp>
#include <boost/test/unit_test.hpp>
@@ -45,7 +47,7 @@ Value CallRPC(string args)
}
-BOOST_AUTO_TEST_SUITE(rpc_tests)
+BOOST_FIXTURE_TEST_SUITE(rpc_tests, TestingSetup)
BOOST_AUTO_TEST_CASE(rpc_rawparams)
{
diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp
index 57c49c2dfc..44475076b3 100644
--- a/src/test/rpc_wallet_tests.cpp
+++ b/src/test/rpc_wallet_tests.cpp
@@ -8,6 +8,8 @@
#include "base58.h"
#include "wallet.h"
+#include "test/test_bitcoin.h"
+
#include <boost/algorithm/string.hpp>
#include <boost/test/unit_test.hpp>
@@ -19,7 +21,7 @@ extern Value CallRPC(string args);
extern CWallet* pwalletMain;
-BOOST_AUTO_TEST_SUITE(rpc_wallet_tests)
+BOOST_FIXTURE_TEST_SUITE(rpc_wallet_tests, TestingSetup)
BOOST_AUTO_TEST_CASE(rpc_addmultisig)
{
diff --git a/src/test/sanity_tests.cpp b/src/test/sanity_tests.cpp
index 464a8fbb8c..f5f7f381d3 100644
--- a/src/test/sanity_tests.cpp
+++ b/src/test/sanity_tests.cpp
@@ -4,9 +4,11 @@
#include "compat/sanity.h"
#include "key.h"
+#include "test/test_bitcoin.h"
#include <boost/test/unit_test.hpp>
-BOOST_AUTO_TEST_SUITE(sanity_tests)
+
+BOOST_FIXTURE_TEST_SUITE(sanity_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(basic_sanity)
{
diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp
index 94f2ce1a29..52171b9e3c 100644
--- a/src/test/script_P2SH_tests.cpp
+++ b/src/test/script_P2SH_tests.cpp
@@ -8,6 +8,7 @@
#include "script/script.h"
#include "script/script_error.h"
#include "script/sign.h"
+#include "test/test_bitcoin.h"
#ifdef ENABLE_WALLET
#include "wallet_ismine.h"
@@ -47,7 +48,7 @@ Verify(const CScript& scriptSig, const CScript& scriptPubKey, bool fStrict, Scri
}
-BOOST_AUTO_TEST_SUITE(script_P2SH_tests)
+BOOST_FIXTURE_TEST_SUITE(script_P2SH_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(sign)
{
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
index e410b59710..c0614cca43 100644
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -13,6 +13,7 @@
#include "script/script_error.h"
#include "script/sign.h"
#include "util.h"
+#include "test/test_bitcoin.h"
#if defined(HAVE_CONSENSUS_LIB)
#include "script/bitcoinconsensus.h"
@@ -53,7 +54,7 @@ read_json(const std::string& jsondata)
return v.get_array();
}
-BOOST_AUTO_TEST_SUITE(script_tests)
+BOOST_FIXTURE_TEST_SUITE(script_tests, BasicTestingSetup)
CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey)
{
diff --git a/src/test/scriptnum_tests.cpp b/src/test/scriptnum_tests.cpp
index cfbaf26e70..24c7dd3d5a 100644
--- a/src/test/scriptnum_tests.cpp
+++ b/src/test/scriptnum_tests.cpp
@@ -4,10 +4,13 @@
#include "bignum.h"
#include "script/script.h"
+#include "test/test_bitcoin.h"
+
#include <boost/test/unit_test.hpp>
#include <limits.h>
#include <stdint.h>
-BOOST_AUTO_TEST_SUITE(scriptnum_tests)
+
+BOOST_FIXTURE_TEST_SUITE(scriptnum_tests, BasicTestingSetup)
static const int64_t values[] = \
{ 0, 1, CHAR_MIN, CHAR_MAX, UCHAR_MAX, SHRT_MIN, USHRT_MAX, INT_MIN, INT_MAX, UINT_MAX, LONG_MIN, LONG_MAX };
diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp
index fe49af711b..cc8f2b788d 100644
--- a/src/test/serialize_tests.cpp
+++ b/src/test/serialize_tests.cpp
@@ -4,6 +4,8 @@
#include "serialize.h"
#include "streams.h"
+#include "hash.h"
+#include "test/test_bitcoin.h"
#include <stdint.h>
@@ -11,7 +13,120 @@
using namespace std;
-BOOST_AUTO_TEST_SUITE(serialize_tests)
+BOOST_FIXTURE_TEST_SUITE(serialize_tests, BasicTestingSetup)
+
+BOOST_AUTO_TEST_CASE(sizes)
+{
+ BOOST_CHECK_EQUAL(sizeof(char), GetSerializeSize(char(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(int8_t), GetSerializeSize(int8_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(uint8_t), GetSerializeSize(uint8_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(int16_t), GetSerializeSize(int16_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(uint16_t), GetSerializeSize(uint16_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(int32_t), GetSerializeSize(int32_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(uint32_t), GetSerializeSize(uint32_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(int64_t), GetSerializeSize(int64_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(uint64_t), GetSerializeSize(uint64_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(float), GetSerializeSize(float(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(double), GetSerializeSize(double(0), 0));
+ // Bool is serialized as char
+ BOOST_CHECK_EQUAL(sizeof(char), GetSerializeSize(bool(0), 0));
+
+ // Sanity-check GetSerializeSize and c++ type matching
+ BOOST_CHECK_EQUAL(GetSerializeSize(char(0), 0), 1);
+ BOOST_CHECK_EQUAL(GetSerializeSize(int8_t(0), 0), 1);
+ BOOST_CHECK_EQUAL(GetSerializeSize(uint8_t(0), 0), 1);
+ BOOST_CHECK_EQUAL(GetSerializeSize(int16_t(0), 0), 2);
+ BOOST_CHECK_EQUAL(GetSerializeSize(uint16_t(0), 0), 2);
+ BOOST_CHECK_EQUAL(GetSerializeSize(int32_t(0), 0), 4);
+ BOOST_CHECK_EQUAL(GetSerializeSize(uint32_t(0), 0), 4);
+ BOOST_CHECK_EQUAL(GetSerializeSize(int64_t(0), 0), 8);
+ BOOST_CHECK_EQUAL(GetSerializeSize(uint64_t(0), 0), 8);
+ BOOST_CHECK_EQUAL(GetSerializeSize(float(0), 0), 4);
+ BOOST_CHECK_EQUAL(GetSerializeSize(double(0), 0), 8);
+ BOOST_CHECK_EQUAL(GetSerializeSize(bool(0), 0), 1);
+}
+
+BOOST_AUTO_TEST_CASE(floats_conversion)
+{
+ // Choose values that map unambigiously to binary floating point to avoid
+ // rounding issues at the compiler side.
+ BOOST_CHECK_EQUAL(ser_uint32_to_float(0x00000000), 0.0F);
+ BOOST_CHECK_EQUAL(ser_uint32_to_float(0x3f000000), 0.5F);
+ BOOST_CHECK_EQUAL(ser_uint32_to_float(0x3f800000), 1.0F);
+ BOOST_CHECK_EQUAL(ser_uint32_to_float(0x40000000), 2.0F);
+ BOOST_CHECK_EQUAL(ser_uint32_to_float(0x40800000), 4.0F);
+ BOOST_CHECK_EQUAL(ser_uint32_to_float(0x44444444), 785.066650390625F);
+
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(0.0F), 0x00000000);
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(0.5F), 0x3f000000);
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(1.0F), 0x3f800000);
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(2.0F), 0x40000000);
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(4.0F), 0x40800000);
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(785.066650390625F), 0x44444444);
+}
+
+BOOST_AUTO_TEST_CASE(doubles_conversion)
+{
+ // Choose values that map unambigiously to binary floating point to avoid
+ // rounding issues at the compiler side.
+ BOOST_CHECK_EQUAL(ser_uint64_to_double(0x0000000000000000ULL), 0.0);
+ BOOST_CHECK_EQUAL(ser_uint64_to_double(0x3fe0000000000000ULL), 0.5);
+ BOOST_CHECK_EQUAL(ser_uint64_to_double(0x3ff0000000000000ULL), 1.0);
+ BOOST_CHECK_EQUAL(ser_uint64_to_double(0x4000000000000000ULL), 2.0);
+ BOOST_CHECK_EQUAL(ser_uint64_to_double(0x4010000000000000ULL), 4.0);
+ BOOST_CHECK_EQUAL(ser_uint64_to_double(0x4088888880000000ULL), 785.066650390625);
+
+ BOOST_CHECK_EQUAL(ser_double_to_uint64(0.0), 0x0000000000000000ULL);
+ BOOST_CHECK_EQUAL(ser_double_to_uint64(0.5), 0x3fe0000000000000ULL);
+ BOOST_CHECK_EQUAL(ser_double_to_uint64(1.0), 0x3ff0000000000000ULL);
+ BOOST_CHECK_EQUAL(ser_double_to_uint64(2.0), 0x4000000000000000ULL);
+ BOOST_CHECK_EQUAL(ser_double_to_uint64(4.0), 0x4010000000000000ULL);
+ BOOST_CHECK_EQUAL(ser_double_to_uint64(785.066650390625), 0x4088888880000000ULL);
+}
+/*
+Python code to generate the below hashes:
+
+ def reversed_hex(x):
+ return binascii.hexlify(''.join(reversed(x)))
+ def dsha256(x):
+ return hashlib.sha256(hashlib.sha256(x).digest()).digest()
+
+ reversed_hex(dsha256(''.join(struct.pack('<f', x) for x in range(0,1000)))) == '8e8b4cf3e4df8b332057e3e23af42ebc663b61e0495d5e7e32d85099d7f3fe0c'
+ reversed_hex(dsha256(''.join(struct.pack('<d', x) for x in range(0,1000)))) == '43d0c82591953c4eafe114590d392676a01585d25b25d433557f0d7878b23f96'
+*/
+BOOST_AUTO_TEST_CASE(floats)
+{
+ CDataStream ss(SER_DISK, 0);
+ // encode
+ for (int i = 0; i < 1000; i++) {
+ ss << float(i);
+ }
+ BOOST_CHECK(Hash(ss.begin(), ss.end()) == uint256S("8e8b4cf3e4df8b332057e3e23af42ebc663b61e0495d5e7e32d85099d7f3fe0c"));
+
+ // decode
+ for (int i = 0; i < 1000; i++) {
+ float j;
+ ss >> j;
+ BOOST_CHECK_MESSAGE(i == j, "decoded:" << j << " expected:" << i);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(doubles)
+{
+ CDataStream ss(SER_DISK, 0);
+ // encode
+ for (int i = 0; i < 1000; i++) {
+ ss << double(i);
+ }
+ BOOST_CHECK(Hash(ss.begin(), ss.end()) == uint256S("43d0c82591953c4eafe114590d392676a01585d25b25d433557f0d7878b23f96"));
+
+ // decode
+ for (int i = 0; i < 1000; i++) {
+ double j;
+ ss >> j;
+ BOOST_CHECK_MESSAGE(i == j, "decoded:" << j << " expected:" << i);
+ }
+}
BOOST_AUTO_TEST_CASE(varints)
{
diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp
index ea41dbcde2..afb7a41bbd 100644
--- a/src/test/sighash_tests.cpp
+++ b/src/test/sighash_tests.cpp
@@ -10,6 +10,7 @@
#include "script/interpreter.h"
#include "util.h"
#include "version.h"
+#include "test/test_bitcoin.h"
#include <iostream>
@@ -115,7 +116,7 @@ void static RandomTransaction(CMutableTransaction &tx, bool fSingle) {
}
}
-BOOST_AUTO_TEST_SUITE(sighash_tests)
+BOOST_FIXTURE_TEST_SUITE(sighash_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(sighash_test)
{
diff --git a/src/test/sigopcount_tests.cpp b/src/test/sigopcount_tests.cpp
index 3c8264d89d..b26fed99f2 100644
--- a/src/test/sigopcount_tests.cpp
+++ b/src/test/sigopcount_tests.cpp
@@ -7,6 +7,7 @@
#include "script/script.h"
#include "script/standard.h"
#include "uint256.h"
+#include "test/test_bitcoin.h"
#include <vector>
@@ -23,7 +24,7 @@ Serialize(const CScript& s)
return sSerialized;
}
-BOOST_AUTO_TEST_SUITE(sigopcount_tests)
+BOOST_FIXTURE_TEST_SUITE(sigopcount_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(GetSigOpCount)
{
diff --git a/src/test/skiplist_tests.cpp b/src/test/skiplist_tests.cpp
index c75e21a2ad..86a4bc6727 100644
--- a/src/test/skiplist_tests.cpp
+++ b/src/test/skiplist_tests.cpp
@@ -5,6 +5,7 @@
#include "main.h"
#include "random.h"
#include "util.h"
+#include "test/test_bitcoin.h"
#include <vector>
@@ -12,7 +13,7 @@
#define SKIPLIST_LENGTH 300000
-BOOST_AUTO_TEST_SUITE(skiplist_tests)
+BOOST_FIXTURE_TEST_SUITE(skiplist_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(skiplist_test)
{
diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp
index f2dae99d69..48e49ed757 100644
--- a/src/test/test_bitcoin.cpp
+++ b/src/test/test_bitcoin.cpp
@@ -4,6 +4,8 @@
#define BOOST_TEST_MODULE Bitcoin Test Suite
+#include "test_bitcoin.h"
+
#include "main.h"
#include "random.h"
#include "txdb.h"
@@ -24,18 +26,21 @@ CWallet* pwalletMain;
extern bool fPrintToConsole;
extern void noui_connect();
-struct TestingSetup {
- CCoinsViewDB *pcoinsdbview;
- boost::filesystem::path pathTemp;
- boost::thread_group threadGroup;
-
- TestingSetup() {
+BasicTestingSetup::BasicTestingSetup()
+{
fPrintToDebugLog = false; // don't want to write to debug.log file
- SelectParams(CBaseChainParams::UNITTEST);
- noui_connect();
+ SelectParams(CBaseChainParams::MAIN);
+}
+BasicTestingSetup::~BasicTestingSetup()
+{
+}
+
+TestingSetup::TestingSetup()
+{
#ifdef ENABLE_WALLET
bitdb.MakeMock();
#endif
+ ClearDatadirCache();
pathTemp = GetTempPath() / strprintf("test_bitcoin_%lu_%i", (unsigned long)GetTime(), (int)(GetRand(100000)));
boost::filesystem::create_directories(pathTemp);
mapArgs["-datadir"] = pathTemp.string();
@@ -53,27 +58,28 @@ struct TestingSetup {
for (int i=0; i < nScriptCheckThreads-1; i++)
threadGroup.create_thread(&ThreadScriptCheck);
RegisterNodeSignals(GetNodeSignals());
- }
- ~TestingSetup()
- {
+}
+
+TestingSetup::~TestingSetup()
+{
+ UnregisterNodeSignals(GetNodeSignals());
threadGroup.interrupt_all();
threadGroup.join_all();
- UnregisterNodeSignals(GetNodeSignals());
#ifdef ENABLE_WALLET
+ UnregisterValidationInterface(pwalletMain);
delete pwalletMain;
pwalletMain = NULL;
#endif
+ UnloadBlockIndex();
delete pcoinsTip;
delete pcoinsdbview;
delete pblocktree;
#ifdef ENABLE_WALLET
bitdb.Flush(true);
+ bitdb.Reset();
#endif
boost::filesystem::remove_all(pathTemp);
- }
-};
-
-BOOST_GLOBAL_FIXTURE(TestingSetup);
+}
void Shutdown(void* parg)
{
diff --git a/src/test/test_bitcoin.h b/src/test/test_bitcoin.h
new file mode 100644
index 0000000000..2f75332d40
--- /dev/null
+++ b/src/test/test_bitcoin.h
@@ -0,0 +1,30 @@
+#ifndef BITCOIN_TEST_TEST_BITCOIN_H
+#define BITCOIN_TEST_TEST_BITCOIN_H
+
+#include "txdb.h"
+
+#include <boost/filesystem.hpp>
+#include <boost/thread.hpp>
+
+/** Basic testing setup.
+ * This just configures logging and chain parameters.
+ */
+struct BasicTestingSetup {
+ BasicTestingSetup();
+ ~BasicTestingSetup();
+};
+
+/** Testing setup that configures a complete environment.
+ * Included are data directory, coins database, script check threads
+ * and wallet (if enabled) setup.
+ */
+struct TestingSetup: public BasicTestingSetup {
+ CCoinsViewDB *pcoinsdbview;
+ boost::filesystem::path pathTemp;
+ boost::thread_group threadGroup;
+
+ TestingSetup();
+ ~TestingSetup();
+};
+
+#endif
diff --git a/src/test/timedata_tests.cpp b/src/test/timedata_tests.cpp
index 58ed963274..887cfb4761 100644
--- a/src/test/timedata_tests.cpp
+++ b/src/test/timedata_tests.cpp
@@ -3,12 +3,13 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
//
#include "timedata.h"
+#include "test/test_bitcoin.h"
#include <boost/test/unit_test.hpp>
using namespace std;
-BOOST_AUTO_TEST_SUITE(timedata_tests)
+BOOST_FIXTURE_TEST_SUITE(timedata_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(util_MedianFilter)
{
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index 52adfea992..2a3083316e 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -4,6 +4,7 @@
#include "data/tx_invalid.json.h"
#include "data/tx_valid.json.h"
+#include "test/test_bitcoin.h"
#include "clientversion.h"
#include "key.h"
@@ -75,7 +76,7 @@ string FormatScriptFlags(unsigned int flags)
return ret.substr(0, ret.size() - 1);
}
-BOOST_AUTO_TEST_SUITE(transaction_tests)
+BOOST_FIXTURE_TEST_SUITE(transaction_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(tx_valid)
{
diff --git a/src/test/uint256_tests.cpp b/src/test/uint256_tests.cpp
index 5b33846ba9..426d296a9a 100644
--- a/src/test/uint256_tests.cpp
+++ b/src/test/uint256_tests.cpp
@@ -4,6 +4,7 @@
#include "arith_uint256.h"
#include "uint256.h"
#include "version.h"
+#include "test/test_bitcoin.h"
#include <boost/test/unit_test.hpp>
#include <stdint.h>
@@ -14,7 +15,7 @@
#include <string>
#include <stdio.h>
-BOOST_AUTO_TEST_SUITE(uint256_tests)
+BOOST_FIXTURE_TEST_SUITE(uint256_tests, BasicTestingSetup)
const unsigned char R1Array[] =
"\x9c\x52\x4a\xdb\xcf\x56\x11\x12\x2b\x29\x12\x5e\x5d\x35\xd2\xd2"
diff --git a/src/test/univalue_tests.cpp b/src/test/univalue_tests.cpp
index 5f0c1deb8e..8cecfbf651 100644
--- a/src/test/univalue_tests.cpp
+++ b/src/test/univalue_tests.cpp
@@ -7,12 +7,13 @@
#include <string>
#include <map>
#include "univalue/univalue.h"
+#include "test/test_bitcoin.h"
#include <boost/test/unit_test.hpp>
using namespace std;
-BOOST_AUTO_TEST_SUITE(univalue_tests)
+BOOST_FIXTURE_TEST_SUITE(univalue_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(univalue_constructor)
{
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index d829ec228d..3309e2e387 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -10,6 +10,7 @@
#include "sync.h"
#include "utilstrencodings.h"
#include "utilmoneystr.h"
+#include "test/test_bitcoin.h"
#include <stdint.h>
#include <vector>
@@ -18,7 +19,7 @@
using namespace std;
-BOOST_AUTO_TEST_SUITE(util_tests)
+BOOST_FIXTURE_TEST_SUITE(util_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(util_criticalsection)
{
diff --git a/src/test/wallet_tests.cpp b/src/test/wallet_tests.cpp
index 289cc8c905..25c8fab335 100644
--- a/src/test/wallet_tests.cpp
+++ b/src/test/wallet_tests.cpp
@@ -9,6 +9,8 @@
#include <utility>
#include <vector>
+#include "test/test_bitcoin.h"
+
#include <boost/foreach.hpp>
#include <boost/test/unit_test.hpp>
@@ -23,7 +25,7 @@ using namespace std;
typedef set<pair<const CWalletTx*,unsigned int> > CoinSet;
-BOOST_AUTO_TEST_SUITE(wallet_tests)
+BOOST_FIXTURE_TEST_SUITE(wallet_tests, TestingSetup)
static CWallet wallet;
static vector<COutput> vCoins;
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index 6e0f7e9c5a..0d50660327 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -337,7 +337,7 @@ public:
void Write(CAutoFile& fileout) const
{
fileout << nBestSeenHeight;
- fileout << history.size();
+ fileout << (uint32_t)history.size();
BOOST_FOREACH(const CBlockAverage& entry, history)
{
entry.Write(fileout);
@@ -348,7 +348,7 @@ public:
{
int nFileBestSeenHeight;
filein >> nFileBestSeenHeight;
- size_t numEntries;
+ uint32_t numEntries;
filein >> numEntries;
if (numEntries <= 0 || numEntries > 10000)
throw runtime_error("Corrupt estimates file. Must have between 1 and 10k entries.");
diff --git a/src/util.cpp b/src/util.cpp
index 361b3631f5..792f00b61d 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -346,6 +346,21 @@ bool SoftSetBoolArg(const std::string& strArg, bool fValue)
return SoftSetArg(strArg, std::string("0"));
}
+static const int screenWidth = 79;
+static const int optIndent = 2;
+static const int msgIndent = 7;
+
+std::string HelpMessageGroup(const std::string &message) {
+ return std::string(message) + std::string("\n\n");
+}
+
+std::string HelpMessageOpt(const std::string &option, const std::string &message) {
+ return std::string(optIndent,' ') + std::string(option) +
+ std::string("\n") + std::string(msgIndent,' ') +
+ FormatParagraph(message, screenWidth - msgIndent, msgIndent) +
+ std::string("\n\n");
+}
+
static std::string FormatException(const std::exception* pex, const char* pszThread)
{
#ifdef WIN32
diff --git a/src/util.h b/src/util.h
index bbb0e81039..9b5a4153dd 100644
--- a/src/util.h
+++ b/src/util.h
@@ -94,6 +94,7 @@ bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest);
bool TryCreateDirectory(const boost::filesystem::path& p);
boost::filesystem::path GetDefaultDataDir();
const boost::filesystem::path &GetDataDir(bool fNetSpecific = true);
+void ClearDatadirCache();
boost::filesystem::path GetConfigFile();
#ifndef WIN32
boost::filesystem::path GetPidFile();
@@ -161,6 +162,23 @@ bool SoftSetArg(const std::string& strArg, const std::string& strValue);
*/
bool SoftSetBoolArg(const std::string& strArg, bool fValue);
+/**
+ * Format a string to be used as group of options in help messages
+ *
+ * @param message Group name (e.g. "RPC server options:")
+ * @return the formatted string
+ */
+std::string HelpMessageGroup(const std::string& message);
+
+/**
+ * Format a string to be used as option description in help messages
+ *
+ * @param option Option message (e.g. "-rpcuser=<user>")
+ * @param message Option description (e.g. "Username for JSON-RPC connections")
+ * @return the formatted string
+ */
+std::string HelpMessageOpt(const std::string& option, const std::string& message);
+
void SetThreadPriority(int nPriority);
void RenameThread(const char* name);
diff --git a/src/walletdb.cpp b/src/walletdb.cpp
index b2daf036ff..ddec57d9a9 100644
--- a/src/walletdb.cpp
+++ b/src/walletdb.cpp
@@ -903,8 +903,8 @@ bool CWalletDB::Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys)
int64_t now = GetTime();
std::string newFilename = strprintf("wallet.%d.bak", now);
- int result = dbenv.dbenv.dbrename(NULL, filename.c_str(), NULL,
- newFilename.c_str(), DB_AUTO_COMMIT);
+ int result = dbenv.dbenv->dbrename(NULL, filename.c_str(), NULL,
+ newFilename.c_str(), DB_AUTO_COMMIT);
if (result == 0)
LogPrintf("Renamed %s to %s\n", filename, newFilename);
else
@@ -923,7 +923,7 @@ bool CWalletDB::Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys)
LogPrintf("Salvage(aggressive) found %u records\n", salvagedData.size());
bool fSuccess = allOK;
- boost::scoped_ptr<Db> pdbCopy(new Db(&dbenv.dbenv, 0));
+ boost::scoped_ptr<Db> pdbCopy(new Db(dbenv.dbenv, 0));
int ret = pdbCopy->open(NULL, // Txn pointer
filename.c_str(), // Filename
"main", // Logical db name