aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am68
-rw-r--r--src/Makefile.qt.include4
-rw-r--r--src/Makefile.qttest.include2
-rw-r--r--src/Makefile.test.include2
-rw-r--r--src/addrman.h1
-rw-r--r--src/alert.cpp1
-rw-r--r--src/bitcoin-cli-res.rc2
-rw-r--r--src/bitcoin-cli.cpp9
-rw-r--r--src/chainparams.cpp43
-rw-r--r--src/chainparams.h24
-rw-r--r--src/chainparamsbase.cpp93
-rw-r--r--src/chainparamsbase.h52
-rw-r--r--src/checkpoints.cpp4
-rw-r--r--src/init.cpp51
-rw-r--r--src/main.cpp123
-rw-r--r--src/main.h10
-rw-r--r--src/miner.cpp214
-rw-r--r--src/netbase.cpp3
-rw-r--r--src/pow.cpp119
-rw-r--r--src/pow.h23
-rw-r--r--src/qt/askpassphrasedialog.cpp2
-rw-r--r--src/qt/bitcoin.cpp2
-rw-r--r--src/qt/forms/helpmessagedialog.ui3
-rw-r--r--src/qt/forms/sendcoinsentry.ui2
-rw-r--r--src/qt/forms/signverifymessagedialog.ui4
-rw-r--r--src/qt/guiutil.cpp4
-rw-r--r--src/qt/paymentserver.cpp8
-rw-r--r--src/qt/signverifymessagedialog.cpp1
-rw-r--r--src/qt/test/paymentservertests.cpp1
-rw-r--r--src/qt/transactiondesc.cpp1
-rw-r--r--src/qt/transactionrecord.cpp1
-rw-r--r--src/rpcclient.cpp2
-rw-r--r--src/rpcmining.cpp17
-rw-r--r--src/rpcmisc.cpp5
-rw-r--r--src/rpcnet.cpp1
-rw-r--r--src/rpcprotocol.cpp17
-rw-r--r--src/rpcprotocol.h4
-rw-r--r--src/rpcserver.cpp144
-rw-r--r--src/rpcserver.h11
-rw-r--r--src/rpcwallet.cpp1
-rw-r--r--src/script.cpp3
-rw-r--r--src/script.h2
-rw-r--r--src/test/DoS_tests.cpp88
-rw-r--r--src/test/base58_tests.cpp12
-rw-r--r--src/test/test_bitcoin.cpp1
-rw-r--r--src/timedata.cpp91
-rw-r--r--src/timedata.h17
-rw-r--r--src/txdb.cpp5
-rw-r--r--src/txmempool.cpp29
-rw-r--r--src/txmempool.h6
-rw-r--r--src/util.cpp126
-rw-r--r--src/util.h4
-rw-r--r--src/wallet.cpp5
-rw-r--r--src/wallet.h2
-rw-r--r--src/walletdb.cpp10
-rw-r--r--src/walletdb.h4
56 files changed, 885 insertions, 599 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 5ecded442c..3643e60201 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -20,10 +20,19 @@ endif
BITCOIN_CONFIG_INCLUDES=-I$(builddir)/config
BITCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS)
+LIBBITCOIN_SERVER=libbitcoin_server.a
+LIBBITCOIN_WALLET=libbitcoin_wallet.a
+LIBBITCOIN_COMMON=libbitcoin_common.a
+LIBBITCOIN_CLI=libbitcoin_cli.a
+LIBBITCOIN_UTIL=libbitcoin_util.a
+LIBBITCOIN_CRYPTO=crypto/libbitcoin_crypto.a
+LIBBITCOINQT=qt/libbitcoinqt.a
+
noinst_LIBRARIES = \
libbitcoin_server.a \
libbitcoin_common.a \
libbitcoin_cli.a \
+ libbitcoin_util.a \
crypto/libbitcoin_crypto.a
if ENABLE_WALLET
BITCOIN_INCLUDES += $(BDB_CPPFLAGS)
@@ -50,6 +59,7 @@ BITCOIN_CORE_H = \
base58.h \
bloom.h \
chainparams.h \
+ chainparamsbase.h \
checkpoints.h \
checkqueue.h \
clientversion.h \
@@ -71,6 +81,7 @@ BITCOIN_CORE_H = \
netbase.h \
net.h \
noui.h \
+ pow.h \
protocol.h \
rpcclient.h \
rpcprotocol.h \
@@ -79,6 +90,7 @@ BITCOIN_CORE_H = \
serialize.h \
sync.h \
threadsafety.h \
+ timedata.h \
tinyformat.h \
txdb.h \
txmempool.h \
@@ -105,33 +117,36 @@ obj/build.h: FORCE
@$(MKDIR_P) $(builddir)/obj
@$(top_srcdir)/share/genbuild.sh $(abs_top_builddir)/src/obj/build.h \
$(abs_top_srcdir)
-libbitcoin_common_a-version.$(OBJEXT): obj/build.h
+libbitcoin_util_a-version.$(OBJEXT): obj/build.h
+# server: shared between bitcoind and bitcoin-qt
libbitcoin_server_a_CPPFLAGS = $(BITCOIN_INCLUDES)
libbitcoin_server_a_SOURCES = \
addrman.cpp \
alert.cpp \
bloom.cpp \
checkpoints.cpp \
- coins.cpp \
init.cpp \
- keystore.cpp \
leveldbwrapper.cpp \
main.cpp \
miner.cpp \
net.cpp \
noui.cpp \
+ pow.cpp \
rpcblockchain.cpp \
rpcmining.cpp \
rpcmisc.cpp \
rpcnet.cpp \
rpcrawtransaction.cpp \
rpcserver.cpp \
+ timedata.cpp \
txdb.cpp \
txmempool.cpp \
$(JSON_H) \
$(BITCOIN_CORE_H)
+# wallet: shared between bitcoind and bitcoin-qt, but only linked
+# when wallet enabled
libbitcoin_wallet_a_CPPFLAGS = $(BITCOIN_INCLUDES)
libbitcoin_wallet_a_SOURCES = \
db.cpp \
@@ -142,6 +157,7 @@ libbitcoin_wallet_a_SOURCES = \
walletdb.cpp \
$(BITCOIN_CORE_H)
+# crypto primitives library
crypto_libbitcoin_crypto_a_CPPFLAGS = $(BITCOIN_CONFIG_INCLUDES)
crypto_libbitcoin_crypto_a_SOURCES = \
crypto/sha1.cpp \
@@ -152,18 +168,29 @@ crypto_libbitcoin_crypto_a_SOURCES = \
crypto/sha1.h \
crypto/ripemd160.h
+# common: shared between bitcoind, and bitcoin-qt and non-server tools
libbitcoin_common_a_CPPFLAGS = $(BITCOIN_INCLUDES)
libbitcoin_common_a_SOURCES = \
- base58.cpp \
allocators.cpp \
+ base58.cpp \
chainparams.cpp \
+ coins.cpp \
core.cpp \
hash.cpp \
key.cpp \
+ keystore.cpp \
netbase.cpp \
protocol.cpp \
- rpcprotocol.cpp \
script.cpp \
+ $(BITCOIN_CORE_H)
+
+# util: shared between all executables.
+# This library *must* be included to make sure that the glibc
+# backward-compatibility objects and their sanity checks are linked.
+libbitcoin_util_a_CPPFLAGS = $(BITCOIN_INCLUDES)
+libbitcoin_util_a_SOURCES = \
+ chainparamsbase.cpp \
+ rpcprotocol.cpp \
sync.cpp \
util.cpp \
version.cpp \
@@ -172,22 +199,24 @@ libbitcoin_common_a_SOURCES = \
$(BITCOIN_CORE_H)
if GLIBC_BACK_COMPAT
-libbitcoin_common_a_SOURCES += compat/glibc_compat.cpp
-libbitcoin_common_a_SOURCES += compat/glibcxx_compat.cpp
+libbitcoin_util_a_SOURCES += compat/glibc_compat.cpp
+libbitcoin_util_a_SOURCES += compat/glibcxx_compat.cpp
endif
+# cli: shared between bitcoin-cli and bitcoin-qt
libbitcoin_cli_a_SOURCES = \
rpcclient.cpp \
$(BITCOIN_CORE_H)
-nodist_libbitcoin_common_a_SOURCES = $(srcdir)/obj/build.h
+nodist_libbitcoin_util_a_SOURCES = $(srcdir)/obj/build.h
#
# bitcoind binary #
bitcoind_LDADD = \
- libbitcoin_server.a \
- libbitcoin_common.a \
- crypto/libbitcoin_crypto.a \
+ $(LIBBITCOIN_SERVER) \
+ $(LIBBITCOIN_COMMON) \
+ $(LIBBITCOIN_UTIL) \
+ $(LIBBITCOIN_CRYPTO) \
$(LIBLEVELDB) \
$(LIBMEMENV)
if ENABLE_WALLET
@@ -205,11 +234,13 @@ bitcoind_CPPFLAGS = $(BITCOIN_INCLUDES)
# bitcoin-cli binary #
bitcoin_cli_LDADD = \
- libbitcoin_cli.a \
- libbitcoin_common.a \
- crypto/libbitcoin_crypto.a \
+ $(LIBBITCOIN_CLI) \
+ $(LIBBITCOIN_COMMON) \
+ $(LIBBITCOIN_UTIL) \
+ $(LIBBITCOIN_CRYPTO) \
$(BOOST_LIBS)
-bitcoin_cli_SOURCES = bitcoin-cli.cpp
+bitcoin_cli_SOURCES = \
+ bitcoin-cli.cpp
bitcoin_cli_CPPFLAGS = $(BITCOIN_INCLUDES)
#
@@ -240,13 +271,6 @@ clean-local:
@test -f $(PROTOC)
$(AM_V_GEN) $(PROTOC) --cpp_out=$(@D) --proto_path=$(abspath $(<D) $<)
-LIBBITCOIN_SERVER=libbitcoin_server.a
-LIBBITCOIN_WALLET=libbitcoin_wallet.a
-LIBBITCOIN_COMMON=libbitcoin_common.a
-LIBBITCOIN_CLI=libbitcoin_cli.a
-LIBBITCOIN_CRYPTO=crypto/libbitcoin_crypto.a
-LIBBITCOINQT=qt/libbitcoinqt.a
-
if ENABLE_TESTS
include Makefile.test.include
endif
diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include
index 091138dc38..9df0779ba3 100644
--- a/src/Makefile.qt.include
+++ b/src/Makefile.qt.include
@@ -355,7 +355,7 @@ qt_bitcoin_qt_LDADD = qt/libbitcoinqt.a $(LIBBITCOIN_SERVER)
if ENABLE_WALLET
qt_bitcoin_qt_LDADD += $(LIBBITCOIN_WALLET)
endif
-qt_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_CRYPTO) $(LIBLEVELDB) $(LIBMEMENV) \
+qt_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBLEVELDB) $(LIBMEMENV) \
$(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS)
qt_bitcoin_qt_LDFLAGS = $(QT_LDFLAGS)
@@ -364,7 +364,7 @@ QT_QM=$(QT_TS:.ts=.qm)
.SECONDARY: $(QT_QM)
-qt/bitcoinstrings.cpp: $(libbitcoin_server_a_SOURCES) $(libbitcoin_common_a_SOURCES) $(libbitcoin_cli_a_SOURCES)
+qt/bitcoinstrings.cpp: $(libbitcoin_server_a_SOURCES) $(libbitcoin_common_a_SOURCES) $(libbitcoin_cli_a_SOURCES) $(libbitcoin_util_a_SOURCES)
@test -n $(XGETTEXT) || echo "xgettext is required for updating translations"
$(AM_V_GEN) cd $(top_srcdir); XGETTEXT=$(XGETTEXT) share/qt/extract_strings_qt.py
diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include
index 0aa31a406d..a509f23755 100644
--- a/src/Makefile.qttest.include
+++ b/src/Makefile.qttest.include
@@ -30,7 +30,7 @@ qt_test_test_bitcoin_qt_LDADD = $(LIBBITCOINQT) $(LIBBITCOIN_SERVER)
if ENABLE_WALLET
qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_WALLET)
endif
-qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_CRYPTO) $(LIBLEVELDB) \
+qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBLEVELDB) \
$(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \
$(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS)
qt_test_test_bitcoin_qt_LDFLAGS = $(QT_LDFLAGS)
diff --git a/src/Makefile.test.include b/src/Makefile.test.include
index 64f997f4b5..4dab1773f4 100644
--- a/src/Makefile.test.include
+++ b/src/Makefile.test.include
@@ -63,7 +63,7 @@ endif
test_test_bitcoin_SOURCES = $(BITCOIN_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES)
test_test_bitcoin_CPPFLAGS = $(BITCOIN_INCLUDES) -I$(builddir)/test/ $(TESTDEFS)
-test_test_bitcoin_LDADD = $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_CRYPTO) $(LIBLEVELDB) $(LIBMEMENV) \
+test_test_bitcoin_LDADD = $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBLEVELDB) $(LIBMEMENV) \
$(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB)
if ENABLE_WALLET
test_test_bitcoin_LDADD += $(LIBBITCOIN_WALLET)
diff --git a/src/addrman.h b/src/addrman.h
index 5328a93b45..c4c296560e 100644
--- a/src/addrman.h
+++ b/src/addrman.h
@@ -8,6 +8,7 @@
#include "netbase.h"
#include "protocol.h"
#include "sync.h"
+#include "timedata.h"
#include "util.h"
#include <map>
diff --git a/src/alert.cpp b/src/alert.cpp
index 638f0d7a1c..258a2b52c4 100644
--- a/src/alert.cpp
+++ b/src/alert.cpp
@@ -8,6 +8,7 @@
#include "chainparams.h"
#include "key.h"
#include "net.h"
+#include "timedata.h"
#include "ui_interface.h"
#include "util.h"
diff --git a/src/bitcoin-cli-res.rc b/src/bitcoin-cli-res.rc
index f8bfb3a881..a4a0c47ea5 100644
--- a/src/bitcoin-cli-res.rc
+++ b/src/bitcoin-cli-res.rc
@@ -5,7 +5,7 @@
#define VER_PRODUCTVERSION_STR STRINGIZE(CLIENT_VERSION_MAJOR) "." STRINGIZE(CLIENT_VERSION_MINOR) "." STRINGIZE(CLIENT_VERSION_REVISION) "." STRINGIZE(CLIENT_VERSION_BUILD)
#define VER_FILEVERSION VER_PRODUCTVERSION
#define VER_FILEVERSION_STR VER_PRODUCTVERSION_STR
-#define COPYRIGHT_STR "2009-" STRINGIZE(COPYRIGHT_YEAR) " The Bitcoin Core developers"
+#define COPYRIGHT_STR "2009-" STRINGIZE(COPYRIGHT_YEAR) " The Bitcoin Core Developers"
VS_VERSION_INFO VERSIONINFO
FILEVERSION VER_FILEVERSION
diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp
index 40b45415c4..db39df4b17 100644
--- a/src/bitcoin-cli.cpp
+++ b/src/bitcoin-cli.cpp
@@ -8,7 +8,7 @@
#include "rpcclient.h"
#include "rpcprotocol.h"
#include "ui_interface.h" /* for _(...) */
-#include "chainparams.h"
+#include "chainparamsbase.h"
#include <boost/filesystem/operations.hpp>
@@ -60,12 +60,11 @@ static bool AppInitRPC(int argc, char* argv[])
fprintf(stderr,"Error reading configuration file: %s\n", e.what());
return false;
}
- // Check for -testnet or -regtest parameter (Params() calls are only valid after this clause)
- if (!SelectParamsFromCommandLine()) {
+ // Check for -testnet or -regtest parameter (BaseParams() calls are only valid after this clause)
+ if (!SelectBaseParamsFromCommandLine()) {
fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n");
return false;
}
-
if (argc<2 || mapArgs.count("-?") || mapArgs.count("-help") || mapArgs.count("-version"))
{
std::string strUsage = _("Bitcoin Core RPC client version") + " " + FormatFullVersion() + "\n";
@@ -104,7 +103,7 @@ Object CallRPC(const string& strMethod, const Array& params)
bool fWait = GetBoolArg("-rpcwait", false); // -rpcwait means try until server has started
do {
- bool fConnected = d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", itostr(Params().RPCPort())));
+ bool fConnected = d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", itostr(BaseParams().RPCPort())));
if (fConnected) break;
if (fWait)
MilliSleep(1000);
diff --git a/src/chainparams.cpp b/src/chainparams.cpp
index afbae6fc57..63067a153d 100644
--- a/src/chainparams.cpp
+++ b/src/chainparams.cpp
@@ -99,7 +99,7 @@ unsigned int pnSeed[] =
class CMainParams : public CChainParams {
public:
CMainParams() {
- networkID = CChainParams::MAIN;
+ networkID = CBaseChainParams::MAIN;
strNetworkID = "main";
// The message start string is designed to be unlikely to occur in normal data.
// The characters are rarely used upper ASCII, not valid as UTF-8, and produce
@@ -110,13 +110,14 @@ public:
pchMessageStart[3] = 0xd9;
vAlertPubKey = ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284");
nDefaultPort = 8333;
- nRPCPort = 8332;
bnProofOfWorkLimit = ~uint256(0) >> 32;
nSubsidyHalvingInterval = 210000;
nEnforceBlockUpgradeMajority = 750;
nRejectBlockOutdatedMajority = 950;
nToCheckBlockUpgradeMajority = 1000;
nMinerThreads = 0;
+ nTargetTimespan = 14 * 24 * 60 * 60; // two weeks
+ nTargetSpacing = 10 * 60;
// Build the genesis block. Note that the output of the genesis coinbase cannot
// be spent as it did not originally exist in the database.
@@ -189,7 +190,7 @@ static CMainParams mainParams;
class CTestNetParams : public CMainParams {
public:
CTestNetParams() {
- networkID = CChainParams::TESTNET;
+ networkID = CBaseChainParams::TESTNET;
strNetworkID = "test";
// The message start string is designed to be unlikely to occur in normal data.
// The characters are rarely used upper ASCII, not valid as UTF-8, and produce
@@ -200,11 +201,12 @@ public:
pchMessageStart[3] = 0x07;
vAlertPubKey = ParseHex("04302390343f91cc401d56d68b123028bf52e5fca1939df127f63c6467cdf9c8e2c14b61104cf817d0b780da337893ecc4aaff1309e536162dabbdb45200ca2b0a");
nDefaultPort = 18333;
- nRPCPort = 18332;
nEnforceBlockUpgradeMajority = 51;
nRejectBlockOutdatedMajority = 75;
nToCheckBlockUpgradeMajority = 100;
- strDataDir = "testnet3";
+ nMinerThreads = 0;
+ nTargetTimespan = 14 * 24 * 60 * 60; // two weeks
+ nTargetSpacing = 10 * 60;
// Modify the testnet genesis block so the timestamp is valid for a later start.
genesis.nTime = 1296688602;
@@ -240,7 +242,7 @@ static CTestNetParams testNetParams;
class CRegTestParams : public CTestNetParams {
public:
CRegTestParams() {
- networkID = CChainParams::REGTEST;
+ networkID = CBaseChainParams::REGTEST;
strNetworkID = "regtest";
pchMessageStart[0] = 0xfa;
pchMessageStart[1] = 0xbf;
@@ -251,13 +253,14 @@ public:
nRejectBlockOutdatedMajority = 950;
nToCheckBlockUpgradeMajority = 1000;
nMinerThreads = 1;
+ nTargetTimespan = 14 * 24 * 60 * 60; // two weeks
+ nTargetSpacing = 10 * 60;
bnProofOfWorkLimit = ~uint256(0) >> 1;
genesis.nTime = 1296688602;
genesis.nBits = 0x207fffff;
genesis.nNonce = 2;
hashGenesisBlock = genesis.GetHash();
nDefaultPort = 18444;
- strDataDir = "regtest";
assert(hashGenesisBlock == uint256("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"));
vSeeds.clear(); // Regtest mode doesn't have any DNS seeds.
@@ -272,21 +275,23 @@ public:
};
static CRegTestParams regTestParams;
-static CChainParams *pCurrentParams = &mainParams;
+static CChainParams *pCurrentParams = 0;
const CChainParams &Params() {
+ assert(pCurrentParams);
return *pCurrentParams;
}
-void SelectParams(CChainParams::Network network) {
+void SelectParams(CBaseChainParams::Network network) {
+ SelectBaseParams(network);
switch (network) {
- case CChainParams::MAIN:
+ case CBaseChainParams::MAIN:
pCurrentParams = &mainParams;
break;
- case CChainParams::TESTNET:
+ case CBaseChainParams::TESTNET:
pCurrentParams = &testNetParams;
break;
- case CChainParams::REGTEST:
+ case CBaseChainParams::REGTEST:
pCurrentParams = &regTestParams;
break;
default:
@@ -296,19 +301,9 @@ void SelectParams(CChainParams::Network network) {
}
bool SelectParamsFromCommandLine() {
- bool fRegTest = GetBoolArg("-regtest", false);
- bool fTestNet = GetBoolArg("-testnet", false);
-
- if (fTestNet && fRegTest) {
+ if (!SelectBaseParamsFromCommandLine())
return false;
- }
- if (fRegTest) {
- SelectParams(CChainParams::REGTEST);
- } else if (fTestNet) {
- SelectParams(CChainParams::TESTNET);
- } else {
- SelectParams(CChainParams::MAIN);
- }
+ SelectParams(BaseParams().NetworkID());
return true;
}
diff --git a/src/chainparams.h b/src/chainparams.h
index c0a6ebda6b..446256ba82 100644
--- a/src/chainparams.h
+++ b/src/chainparams.h
@@ -7,6 +7,7 @@
#define BITCOIN_CHAIN_PARAMS_H
#include "core.h"
+#include "chainparamsbase.h"
#include "protocol.h"
#include "uint256.h"
@@ -29,14 +30,6 @@ struct CDNSSeedData {
class CChainParams
{
public:
- enum Network {
- MAIN,
- TESTNET,
- REGTEST,
-
- MAX_NETWORK_TYPES
- };
-
enum Base58Type {
PUBKEY_ADDRESS,
SCRIPT_ADDRESS,
@@ -70,17 +63,18 @@ public:
bool AllowMinDifficultyBlocks() const { return fAllowMinDifficultyBlocks; }
/* Make standard checks */
bool RequireStandard() const { return fRequireStandard; }
- const std::string& DataDir() const { return strDataDir; }
+ int64_t TargetTimespan() const { return nTargetTimespan; }
+ int64_t TargetSpacing() const { return nTargetSpacing; }
+ int64_t Interval() const { return nTargetTimespan / nTargetSpacing; }
/* Make miner stop after a block is found. In RPC, don't return
* until nGenProcLimit blocks are generated */
bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; }
- Network NetworkID() const { return networkID; }
+ CBaseChainParams::Network NetworkID() const { return networkID; }
/* Return the BIP70 network string (main, test or regtest) */
std::string NetworkIDString() const { return strNetworkID; }
const std::vector<CDNSSeedData>& DNSSeeds() const { return vSeeds; }
const std::vector<unsigned char>& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; }
const std::vector<CAddress>& FixedSeeds() const { return vFixedSeeds; }
- int RPCPort() const { return nRPCPort; }
protected:
CChainParams() {}
@@ -89,17 +83,17 @@ protected:
// Raw pub key bytes for the broadcast alert signing key.
std::vector<unsigned char> vAlertPubKey;
int nDefaultPort;
- int nRPCPort;
uint256 bnProofOfWorkLimit;
int nSubsidyHalvingInterval;
int nEnforceBlockUpgradeMajority;
int nRejectBlockOutdatedMajority;
int nToCheckBlockUpgradeMajority;
- std::string strDataDir;
+ int64_t nTargetTimespan;
+ int64_t nTargetSpacing;
int nMinerThreads;
std::vector<CDNSSeedData> vSeeds;
std::vector<unsigned char> base58Prefixes[MAX_BASE58_TYPES];
- Network networkID;
+ CBaseChainParams::Network networkID;
std::string strNetworkID;
CBlock genesis;
std::vector<CAddress> vFixedSeeds;
@@ -118,7 +112,7 @@ protected:
const CChainParams &Params();
/** Sets the params returned by Params() to those for the given network. */
-void SelectParams(CChainParams::Network network);
+void SelectParams(CBaseChainParams::Network network);
/**
* Looks for -regtest or -testnet and then calls SelectParams as appropriate.
diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp
new file mode 100644
index 0000000000..19a9e72cc9
--- /dev/null
+++ b/src/chainparamsbase.cpp
@@ -0,0 +1,93 @@
+// Copyright (c) 2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "chainparamsbase.h"
+
+#include "assert.h"
+#include "util.h"
+
+#include <boost/assign/list_of.hpp>
+
+using namespace boost::assign;
+
+//
+// Main network
+//
+
+class CBaseMainParams : public CBaseChainParams {
+public:
+ CBaseMainParams() {
+ networkID = CBaseChainParams::MAIN;
+ nRPCPort = 8332;
+ }
+};
+static CBaseMainParams mainParams;
+
+//
+// Testnet (v3)
+//
+class CBaseTestNetParams : public CBaseMainParams {
+public:
+ CBaseTestNetParams() {
+ networkID = CBaseChainParams::TESTNET;
+ nRPCPort = 18332;
+ strDataDir = "testnet3";
+ }
+};
+static CBaseTestNetParams testNetParams;
+
+//
+// Regression test
+//
+class CBaseRegTestParams : public CBaseTestNetParams {
+public:
+ CBaseRegTestParams() {
+ networkID = CBaseChainParams::REGTEST;
+ strDataDir = "regtest";
+ }
+};
+static CBaseRegTestParams regTestParams;
+
+static CBaseChainParams *pCurrentBaseParams = 0;
+
+const CBaseChainParams &BaseParams() {
+ assert(pCurrentBaseParams);
+ return *pCurrentBaseParams;
+}
+
+void SelectBaseParams(CBaseChainParams::Network network) {
+ switch (network) {
+ case CBaseChainParams::MAIN:
+ pCurrentBaseParams = &mainParams;
+ break;
+ case CBaseChainParams::TESTNET:
+ pCurrentBaseParams = &testNetParams;
+ break;
+ case CBaseChainParams::REGTEST:
+ pCurrentBaseParams = &regTestParams;
+ break;
+ default:
+ assert(false && "Unimplemented network");
+ return;
+ }
+}
+
+bool SelectBaseParamsFromCommandLine() {
+ bool fRegTest = GetBoolArg("-regtest", false);
+ bool fTestNet = GetBoolArg("-testnet", false);
+
+ if (fTestNet && fRegTest) {
+ return false;
+ }
+
+ if (fRegTest) {
+ SelectBaseParams(CBaseChainParams::REGTEST);
+ } else if (fTestNet) {
+ SelectBaseParams(CBaseChainParams::TESTNET);
+ } else {
+ SelectBaseParams(CBaseChainParams::MAIN);
+ }
+ return true;
+}
diff --git a/src/chainparamsbase.h b/src/chainparamsbase.h
new file mode 100644
index 0000000000..4a3b268909
--- /dev/null
+++ b/src/chainparamsbase.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2014 The Bitcoin developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_CHAIN_PARAMS_BASE_H
+#define BITCOIN_CHAIN_PARAMS_BASE_H
+
+#include <vector>
+#include <string>
+
+/**
+ * CBaseChainParams defines the base parameters (shared between bitcoin-cli and bitcoind)
+ * of a given instance of the Bitcoin system.
+ */
+class CBaseChainParams
+{
+public:
+ enum Network {
+ MAIN,
+ TESTNET,
+ REGTEST,
+
+ MAX_NETWORK_TYPES
+ };
+
+ const std::string& DataDir() const { return strDataDir; }
+ int RPCPort() const { return nRPCPort; }
+ Network NetworkID() const { return networkID; }
+protected:
+ CBaseChainParams() {}
+
+ int nRPCPort;
+ std::string strDataDir;
+ Network networkID;
+};
+
+/**
+ * Return the currently selected parameters. This won't change after app startup
+ * outside of the unit tests.
+ */
+const CBaseChainParams &BaseParams();
+
+/** Sets the params returned by Params() to those for the given network. */
+void SelectBaseParams(CBaseChainParams::Network network);
+
+/**
+ * Looks for -regtest or -testnet and then calls SelectParams as appropriate.
+ * Returns false if an invalid combination is given.
+ */
+bool SelectBaseParamsFromCommandLine();
+
+#endif
diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp
index 926949e06a..75ac418916 100644
--- a/src/checkpoints.cpp
+++ b/src/checkpoints.cpp
@@ -83,9 +83,9 @@ namespace Checkpoints
};
const CCheckpointData &Checkpoints() {
- if (Params().NetworkID() == CChainParams::TESTNET)
+ if (Params().NetworkID() == CBaseChainParams::TESTNET)
return dataTestnet;
- else if (Params().NetworkID() == CChainParams::MAIN)
+ else if (Params().NetworkID() == CBaseChainParams::MAIN)
return data;
else
return dataRegtest;
diff --git a/src/init.cpp b/src/init.cpp
index ff7a9011a5..c7170b0f2d 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -260,7 +260,8 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += " -upgradewallet " + _("Upgrade wallet to latest format") + " " + _("on startup") + "\n";
strUsage += " -wallet=<file> " + _("Specify wallet file (within data directory)") + " " + _("(default: wallet.dat)") + "\n";
strUsage += " -walletnotify=<cmd> " + _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)") + "\n";
- strUsage += " -zapwallettxes " + _("Clear list of wallet transactions (diagnostic tool; implies -rescan)") + "\n";
+ strUsage += " -zapwallettxes=<mode> " + _("Delete all wallet transactions and only recover those part of the blockchain through -rescan on startup") + "\n";
+ strUsage += " " + _("(default: 1, 1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)") + "\n";
#endif
strUsage += "\n" + _("Debugging/Testing options:") + "\n";
@@ -308,6 +309,8 @@ std::string HelpMessage(HelpMessageMode mode)
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 " + _("Relay and mine data carrier transactions (default: 1)") + "\n";
strUsage += "\n" + _("Block creation options:") + "\n";
strUsage += " -blockminsize=<n> " + _("Set minimum block size in bytes (default: 0)") + "\n";
strUsage += " -blockmaxsize=<n> " + strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE) + "\n";
@@ -536,7 +539,7 @@ bool AppInit2(boost::thread_group& threadGroup)
// -zapwallettx implies a rescan
if (GetBoolArg("-zapwallettxes", false)) {
if (SoftSetBoolArg("-rescan", true))
- LogPrintf("AppInit2 : parameter interaction: -zapwallettxes=1 -> setting -rescan=1\n");
+ LogPrintf("AppInit2 : parameter interaction: -zapwallettxes=<mode> -> setting -rescan=1\n");
}
// Make sure enough file descriptors are available
@@ -560,6 +563,9 @@ bool AppInit2(boost::thread_group& threadGroup)
// Check for -debugnet (deprecated)
if (GetBoolArg("-debugnet", false))
InitWarning(_("Warning: Deprecated argument -debugnet ignored, use -debug=net"));
+ // Check for -tor - as this is a privacy risk to continue, exit here
+ if (GetBoolArg("-tor", false))
+ return InitError(_("Error: Unsupported argument -tor found, use -onion."));
fBenchmark = GetBoolArg("-benchmark", false);
// Checkmempool defaults to true in regtest mode
@@ -766,19 +772,15 @@ bool AppInit2(boost::thread_group& threadGroup)
}
// -onion can override normal proxy, -noonion disables tor entirely
- // -tor here is a temporary backwards compatibility measure
- if (mapArgs.count("-tor"))
- printf("Notice: option -tor has been replaced with -onion and will be removed in a later version.\n");
if (!(mapArgs.count("-onion") && mapArgs["-onion"] == "0") &&
- !(mapArgs.count("-tor") && mapArgs["-tor"] == "0") &&
- (fProxy || mapArgs.count("-onion") || mapArgs.count("-tor"))) {
+ (fProxy || mapArgs.count("-onion"))) {
CService addrOnion;
- if (!mapArgs.count("-onion") && !mapArgs.count("-tor"))
+ if (!mapArgs.count("-onion"))
addrOnion = addrProxy;
else
- addrOnion = mapArgs.count("-onion")?CService(mapArgs["-onion"], 9050):CService(mapArgs["-tor"], 9050);
+ addrOnion = CService(mapArgs["-onion"], 9050);
if (!addrOnion.IsValid())
- return InitError(strprintf(_("Invalid -onion address: '%s'"), mapArgs.count("-onion")?mapArgs["-onion"]:mapArgs["-tor"]));
+ return InitError(strprintf(_("Invalid -onion address: '%s'"), mapArgs["-onion"]));
SetProxy(NET_TOR, addrOnion, 5);
SetReachable(NET_TOR);
}
@@ -993,11 +995,15 @@ bool AppInit2(boost::thread_group& threadGroup)
pwalletMain = NULL;
LogPrintf("Wallet disabled!\n");
} else {
+
+ // needed to restore wallet transaction meta data after -zapwallettxes
+ std::vector<CWalletTx> vWtx;
+
if (GetBoolArg("-zapwallettxes", false)) {
uiInterface.InitMessage(_("Zapping all transactions from wallet..."));
pwalletMain = new CWallet(strWalletFile);
- DBErrors nZapWalletRet = pwalletMain->ZapWalletTx();
+ DBErrors nZapWalletRet = pwalletMain->ZapWalletTx(vWtx);
if (nZapWalletRet != DB_LOAD_OK) {
uiInterface.InitMessage(_("Error loading wallet.dat: Wallet corrupted"));
return false;
@@ -1092,6 +1098,29 @@ bool AppInit2(boost::thread_group& threadGroup)
LogPrintf(" rescan %15dms\n", GetTimeMillis() - nStart);
pwalletMain->SetBestChain(chainActive.GetLocator());
nWalletDBUpdated++;
+
+ // Restore wallet transaction metadata after -zapwallettxes=1
+ if (GetBoolArg("-zapwallettxes", false) && GetArg("-zapwallettxes", "1") != "2")
+ {
+ BOOST_FOREACH(const CWalletTx& wtxOld, vWtx)
+ {
+ uint256 hash = wtxOld.GetHash();
+ std::map<uint256, CWalletTx>::iterator mi = pwalletMain->mapWallet.find(hash);
+ if (mi != pwalletMain->mapWallet.end())
+ {
+ const CWalletTx* copyFrom = &wtxOld;
+ CWalletTx* copyTo = &mi->second;
+ copyTo->mapValue = copyFrom->mapValue;
+ copyTo->vOrderForm = copyFrom->vOrderForm;
+ copyTo->nTimeReceived = copyFrom->nTimeReceived;
+ copyTo->nTimeSmart = copyFrom->nTimeSmart;
+ copyTo->fFromMe = copyFrom->fFromMe;
+ copyTo->strFromAccount = copyFrom->strFromAccount;
+ copyTo->nOrderPos = copyFrom->nOrderPos;
+ copyTo->WriteToDisk();
+ }
+ }
+ }
}
} // (!fDisableWallet)
#else // ENABLE_WALLET
diff --git a/src/main.cpp b/src/main.cpp
index ecabd9ec2c..d86fd3a24d 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -12,6 +12,7 @@
#include "checkqueue.h"
#include "init.h"
#include "net.h"
+#include "pow.h"
#include "txdb.h"
#include "txmempool.h"
#include "ui_interface.h"
@@ -791,6 +792,16 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state)
int64_t GetMinFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree, enum GetMinFee_mode mode)
{
+ {
+ LOCK(mempool.cs);
+ uint256 hash = tx.GetHash();
+ double dPriorityDelta = 0;
+ int64_t nFeeDelta = 0;
+ mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
+ if (dPriorityDelta > 0 || nFeeDelta > 0)
+ return 0;
+ }
+
// Base fee is either minTxFee or minRelayTxFee
CFeeRate baseFeeRate = (mode == GMF_RELAY) ? tx.minRelayTxFee : tx.minTxFee;
@@ -1197,118 +1208,6 @@ int64_t GetBlockValue(int nHeight, int64_t nFees)
return nSubsidy + nFees;
}
-static const int64_t nTargetTimespan = 14 * 24 * 60 * 60; // two weeks
-static const int64_t nTargetSpacing = 10 * 60;
-static const int64_t nInterval = nTargetTimespan / nTargetSpacing;
-
-//
-// minimum amount of work that could possibly be required nTime after
-// minimum work required was nBase
-//
-unsigned int ComputeMinWork(unsigned int nBase, int64_t nTime)
-{
- const uint256 &bnLimit = Params().ProofOfWorkLimit();
- // Testnet has min-difficulty blocks
- // after nTargetSpacing*2 time between blocks:
- if (Params().AllowMinDifficultyBlocks() && nTime > nTargetSpacing*2)
- return bnLimit.GetCompact();
-
- uint256 bnResult;
- bnResult.SetCompact(nBase);
- while (nTime > 0 && bnResult < bnLimit)
- {
- // Maximum 400% adjustment...
- bnResult *= 4;
- // ... in best-case exactly 4-times-normal target time
- nTime -= nTargetTimespan*4;
- }
- if (bnResult > bnLimit)
- bnResult = bnLimit;
- return bnResult.GetCompact();
-}
-
-unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock)
-{
- unsigned int nProofOfWorkLimit = Params().ProofOfWorkLimit().GetCompact();
-
- // Genesis block
- if (pindexLast == NULL)
- return nProofOfWorkLimit;
-
- // Only change once per interval
- if ((pindexLast->nHeight+1) % nInterval != 0)
- {
- if (Params().AllowMinDifficultyBlocks())
- {
- // Special difficulty rule for testnet:
- // If the new block's timestamp is more than 2* 10 minutes
- // then allow mining of a min-difficulty block.
- if (pblock->nTime > pindexLast->nTime + nTargetSpacing*2)
- return nProofOfWorkLimit;
- else
- {
- // Return the last non-special-min-difficulty-rules-block
- const CBlockIndex* pindex = pindexLast;
- while (pindex->pprev && pindex->nHeight % nInterval != 0 && pindex->nBits == nProofOfWorkLimit)
- pindex = pindex->pprev;
- return pindex->nBits;
- }
- }
- return pindexLast->nBits;
- }
-
- // Go back by what we want to be 14 days worth of blocks
- const CBlockIndex* pindexFirst = pindexLast;
- for (int i = 0; pindexFirst && i < nInterval-1; i++)
- pindexFirst = pindexFirst->pprev;
- assert(pindexFirst);
-
- // Limit adjustment step
- int64_t nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
- LogPrintf(" nActualTimespan = %d before bounds\n", nActualTimespan);
- if (nActualTimespan < nTargetTimespan/4)
- nActualTimespan = nTargetTimespan/4;
- if (nActualTimespan > nTargetTimespan*4)
- nActualTimespan = nTargetTimespan*4;
-
- // Retarget
- uint256 bnNew;
- uint256 bnOld;
- bnNew.SetCompact(pindexLast->nBits);
- bnOld = bnNew;
- bnNew *= nActualTimespan;
- bnNew /= nTargetTimespan;
-
- if (bnNew > Params().ProofOfWorkLimit())
- bnNew = Params().ProofOfWorkLimit();
-
- /// debug print
- LogPrintf("GetNextWorkRequired RETARGET\n");
- LogPrintf("nTargetTimespan = %d nActualTimespan = %d\n", nTargetTimespan, nActualTimespan);
- LogPrintf("Before: %08x %s\n", pindexLast->nBits, bnOld.ToString());
- LogPrintf("After: %08x %s\n", bnNew.GetCompact(), bnNew.ToString());
-
- return bnNew.GetCompact();
-}
-
-bool CheckProofOfWork(uint256 hash, unsigned int nBits)
-{
- bool fNegative;
- bool fOverflow;
- uint256 bnTarget;
- bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
-
- // Check range
- if (fNegative || bnTarget == 0 || fOverflow || bnTarget > Params().ProofOfWorkLimit())
- return error("CheckProofOfWork() : nBits below minimum work");
-
- // Check proof of work matches claimed amount
- if (hash > bnTarget)
- return error("CheckProofOfWork() : hash doesn't match nBits");
-
- return true;
-}
-
bool IsInitialBlockDownload()
{
LOCK(cs_main);
diff --git a/src/main.h b/src/main.h
index ff1f742d1e..0332db2163 100644
--- a/src/main.h
+++ b/src/main.h
@@ -148,10 +148,6 @@ bool ProcessMessages(CNode* pfrom);
bool SendMessages(CNode* pto, bool fSendTrickle);
/** Run an instance of the script checking thread */
void ThreadScriptCheck();
-/** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */
-bool CheckProofOfWork(uint256 hash, unsigned int nBits);
-/** Calculate the minimum amount of work a received block needs, without knowing its direct parent */
-unsigned int ComputeMinWork(unsigned int nBase, int64_t nTime);
/** Check whether we are doing an initial block download (synchronizing from disk or network) */
bool IsInitialBlockDownload();
/** Format a string that describes several potential problems detected by the core */
@@ -161,7 +157,6 @@ bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock, b
/** Find the best known block, and make it the tip of the block chain */
bool ActivateBestChain(CValidationState &state);
int64_t GetBlockValue(int nHeight, int64_t nFees);
-unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock);
void UpdateTime(CBlockHeader& block, const CBlockIndex* pindexPrev);
@@ -814,11 +809,6 @@ public:
return (~bnTarget / (bnTarget + 1)) + 1;
}
- bool CheckIndex() const
- {
- return CheckProofOfWork(GetBlockHash(), nBits);
- }
-
enum { nMedianTimeSpan=11 };
int64_t GetMedianTimePast() const
diff --git a/src/miner.cpp b/src/miner.cpp
index 63ce125067..69e53756e0 100644
--- a/src/miner.cpp
+++ b/src/miner.cpp
@@ -3,12 +3,15 @@
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include <inttypes.h>
+
#include "miner.h"
#include "core.h"
#include "hash.h"
#include "main.h"
#include "net.h"
+#include "pow.h"
#ifdef ENABLE_WALLET
#include "wallet.h"
#endif
@@ -49,7 +52,6 @@ public:
}
};
-
uint64_t nLastBlockTx = 0;
uint64_t nLastBlockSize = 0;
@@ -58,8 +60,10 @@ typedef boost::tuple<double, CFeeRate, const CTransaction*> TxPriority;
class TxPriorityCompare
{
bool byFee;
+
public:
TxPriorityCompare(bool _byFee) : byFee(_byFee) { }
+
bool operator()(const TxPriority& a, const TxPriority& b)
{
if (byFee)
@@ -114,6 +118,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
// Collect memory pool transactions into the block
int64_t nFees = 0;
+
{
LOCK2(cs_main, mempool.cs);
CBlockIndex* pindexPrev = chainActive.Tip();
@@ -183,6 +188,9 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
dPriority = tx.ComputePriority(dPriority, nTxSize);
+ uint256 hash = tx.GetHash();
+ mempool.ApplyDeltas(hash, dPriority, nTotalIn);
+
CFeeRate feeRate(nTotalIn-tx.GetValueOut(), nTxSize);
if (porphan)
@@ -224,10 +232,14 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
continue;
// Skip free transactions if we're past the minimum block size:
- if (fSortedByFee && (feeRate < CTransaction::minRelayTxFee) && (nBlockSize + nTxSize >= nBlockMinSize))
+ const uint256& hash = tx.GetHash();
+ double dPriorityDelta = 0;
+ int64_t nFeeDelta = 0;
+ mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
+ if (fSortedByFee && (dPriorityDelta <= 0) && (nFeeDelta <= 0) && (feeRate < CTransaction::minRelayTxFee) && (nBlockSize + nTxSize >= nBlockMinSize))
continue;
- // Prioritize by fee once past the priority size or we run out of high-priority
+ // Prioritise by fee once past the priority size or we run out of high-priority
// transactions:
if (!fSortedByFee &&
((nBlockSize + nTxSize >= nBlockPrioritySize) || !AllowFree(dPriority)))
@@ -254,7 +266,6 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
continue;
CTxUndo txundo;
- const uint256& hash = tx.GetHash();
UpdateCoins(tx, state, view, txundo, pindexPrev->nHeight+1);
// Added
@@ -269,7 +280,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
if (fPrintPriority)
{
LogPrintf("priority %.1f fee %s txid %s\n",
- dPriority, feeRate.ToString(), tx.GetHash().ToString());
+ dPriority, feeRate.ToString(), tx.GetHash().ToString());
}
// Add transactions that depend on this one to the priority queue
@@ -338,7 +349,6 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int&
pblock->hashMerkleRoot = pblock->BuildMerkleTree();
}
-
#ifdef ENABLE_WALLET
//////////////////////////////////////////////////////////////////////////////
//
@@ -353,7 +363,8 @@ int64_t nHPSTimerStart = 0;
// nonce is 0xffff0000 or above, the block is rebuilt and nNonce starts over at
// zero.
//
-bool static ScanHash(const CBlockHeader *pblock, uint32_t& nNonce, uint256 *phash) {
+bool static ScanHash(const CBlockHeader *pblock, uint32_t& nNonce, uint256 *phash)
+{
// Write the first 76 bytes of the block header to a double-SHA256 state.
CHash256 hasher;
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
@@ -361,7 +372,7 @@ bool static ScanHash(const CBlockHeader *pblock, uint32_t& nNonce, uint256 *phas
assert(ss.size() == 80);
hasher.Write((unsigned char*)&ss[0], 76);
- for (;;) {
+ while (true) {
nNonce++;
// Write the last 4 bytes of the block header (the nonce) to a copy of
@@ -439,114 +450,115 @@ void static BitcoinMiner(CWallet *pwallet)
CReserveKey reservekey(pwallet);
unsigned int nExtraNonce = 0;
- try { while (true) {
- if (Params().MiningRequiresPeers()) {
- // Busy-wait for the network to come online so we don't waste time mining
- // on an obsolete chain. In regtest mode we expect to fly solo.
- while (vNodes.empty())
- MilliSleep(1000);
- }
-
- //
- // Create new block
- //
- unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
- CBlockIndex* pindexPrev = chainActive.Tip();
-
- auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey));
- if (!pblocktemplate.get())
- return;
- CBlock *pblock = &pblocktemplate->block;
- IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
-
- LogPrintf("Running BitcoinMiner with %u transactions in block (%u bytes)\n", pblock->vtx.size(),
- ::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION));
-
- //
- // Search
- //
- int64_t nStart = GetTime();
- uint256 hashTarget = uint256().SetCompact(pblock->nBits);
- uint256 hash;
- uint32_t nNonce = 0;
- uint32_t nOldNonce = 0;
- while (true)
- {
- bool fFound = ScanHash(pblock, nNonce, &hash);
- uint32_t nHashesDone = nNonce - nOldNonce;
- nOldNonce = nNonce;
+ try {
+ while (true) {
+ if (Params().MiningRequiresPeers()) {
+ // Busy-wait for the network to come online so we don't waste time mining
+ // on an obsolete chain. In regtest mode we expect to fly solo.
+ while (vNodes.empty())
+ MilliSleep(1000);
+ }
- // Check if something found
- if (fFound)
- {
- if (hash <= hashTarget)
+ //
+ // Create new block
+ //
+ unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
+ CBlockIndex* pindexPrev = chainActive.Tip();
+
+ auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey));
+ if (!pblocktemplate.get())
+ return;
+ CBlock *pblock = &pblocktemplate->block;
+ IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
+
+ LogPrintf("Running BitcoinMiner with %u transactions in block (%u bytes)\n", pblock->vtx.size(),
+ ::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION));
+
+ //
+ // Search
+ //
+ int64_t nStart = GetTime();
+ uint256 hashTarget = uint256().SetCompact(pblock->nBits);
+ uint256 hash;
+ uint32_t nNonce = 0;
+ uint32_t nOldNonce = 0;
+ while (true) {
+ bool fFound = ScanHash(pblock, nNonce, &hash);
+ uint32_t nHashesDone = nNonce - nOldNonce;
+ nOldNonce = nNonce;
+
+ // Check if something found
+ if (fFound)
{
- // Found a solution
- pblock->nNonce = nNonce;
- assert(hash == pblock->GetHash());
+ if (hash <= hashTarget)
+ {
+ // Found a solution
+ pblock->nNonce = nNonce;
+ assert(hash == pblock->GetHash());
- SetThreadPriority(THREAD_PRIORITY_NORMAL);
- CheckWork(pblock, *pwallet, reservekey);
- SetThreadPriority(THREAD_PRIORITY_LOWEST);
+ SetThreadPriority(THREAD_PRIORITY_NORMAL);
+ CheckWork(pblock, *pwallet, reservekey);
+ SetThreadPriority(THREAD_PRIORITY_LOWEST);
- // In regression test mode, stop mining after a block is found.
- if (Params().MineBlocksOnDemand())
- throw boost::thread_interrupted();
+ // In regression test mode, stop mining after a block is found.
+ if (Params().MineBlocksOnDemand())
+ throw boost::thread_interrupted();
- break;
+ break;
+ }
}
- }
- // Meter hashes/sec
- static int64_t nHashCounter;
- if (nHPSTimerStart == 0)
- {
- nHPSTimerStart = GetTimeMillis();
- nHashCounter = 0;
- }
- else
- nHashCounter += nHashesDone;
- if (GetTimeMillis() - nHPSTimerStart > 4000)
- {
- static CCriticalSection cs;
+ // Meter hashes/sec
+ static int64_t nHashCounter;
+ if (nHPSTimerStart == 0)
+ {
+ nHPSTimerStart = GetTimeMillis();
+ nHashCounter = 0;
+ }
+ else
+ nHashCounter += nHashesDone;
+ if (GetTimeMillis() - nHPSTimerStart > 4000)
{
- LOCK(cs);
- if (GetTimeMillis() - nHPSTimerStart > 4000)
+ static CCriticalSection cs;
{
- dHashesPerSec = 1000.0 * nHashCounter / (GetTimeMillis() - nHPSTimerStart);
- nHPSTimerStart = GetTimeMillis();
- nHashCounter = 0;
- static int64_t nLogTime;
- if (GetTime() - nLogTime > 30 * 60)
+ LOCK(cs);
+ if (GetTimeMillis() - nHPSTimerStart > 4000)
{
- nLogTime = GetTime();
- LogPrintf("hashmeter %6.0f khash/s\n", dHashesPerSec/1000.0);
+ dHashesPerSec = 1000.0 * nHashCounter / (GetTimeMillis() - nHPSTimerStart);
+ nHPSTimerStart = GetTimeMillis();
+ nHashCounter = 0;
+ static int64_t nLogTime;
+ if (GetTime() - nLogTime > 30 * 60)
+ {
+ nLogTime = GetTime();
+ LogPrintf("hashmeter %6.0f khash/s\n", dHashesPerSec/1000.0);
+ }
}
}
}
- }
- // Check for stop or if block needs to be rebuilt
- boost::this_thread::interruption_point();
- // Regtest mode doesn't require peers
- if (vNodes.empty() && Params().MiningRequiresPeers())
- break;
- if (nNonce >= 0xffff0000)
- break;
- if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60)
- break;
- if (pindexPrev != chainActive.Tip())
- break;
-
- // Update nTime every few seconds
- UpdateTime(*pblock, pindexPrev);
- if (Params().AllowMinDifficultyBlocks())
- {
- // Changing pblock->nTime can change work required on testnet:
- hashTarget.SetCompact(pblock->nBits);
+ // Check for stop or if block needs to be rebuilt
+ boost::this_thread::interruption_point();
+ // Regtest mode doesn't require peers
+ if (vNodes.empty() && Params().MiningRequiresPeers())
+ break;
+ if (nNonce >= 0xffff0000)
+ break;
+ if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60)
+ break;
+ if (pindexPrev != chainActive.Tip())
+ break;
+
+ // Update nTime every few seconds
+ UpdateTime(*pblock, pindexPrev);
+ if (Params().AllowMinDifficultyBlocks())
+ {
+ // Changing pblock->nTime can change work required on testnet:
+ hashTarget.SetCompact(pblock->nBits);
+ }
}
}
- } }
+ }
catch (boost::thread_interrupted)
{
LogPrintf("BitcoinMiner terminated\n");
@@ -581,4 +593,4 @@ void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads)
minerThreads->create_thread(boost::bind(&BitcoinMiner, pwallet));
}
-#endif
+#endif // ENABLE_WALLET
diff --git a/src/netbase.cpp b/src/netbase.cpp
index 4aa7367f39..3c50174e75 100644
--- a/src/netbase.cpp
+++ b/src/netbase.cpp
@@ -337,8 +337,9 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
if (connect(hSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
{
+ int nErr = WSAGetLastError();
// WSAEINVAL is here because some legacy version of winsock uses it
- if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL)
+ if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL)
{
struct timeval timeout;
timeout.tv_sec = nTimeout / 1000;
diff --git a/src/pow.cpp b/src/pow.cpp
new file mode 100644
index 0000000000..952250decd
--- /dev/null
+++ b/src/pow.cpp
@@ -0,0 +1,119 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "pow.h"
+
+#include "chainparams.h"
+#include "core.h"
+#include "main.h"
+#include "uint256.h"
+
+unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock)
+{
+ unsigned int nProofOfWorkLimit = Params().ProofOfWorkLimit().GetCompact();
+
+ // Genesis block
+ if (pindexLast == NULL)
+ return nProofOfWorkLimit;
+
+ // Only change once per interval
+ if ((pindexLast->nHeight+1) % Params().Interval() != 0)
+ {
+ if (Params().AllowMinDifficultyBlocks())
+ {
+ // Special difficulty rule for testnet:
+ // If the new block's timestamp is more than 2* 10 minutes
+ // then allow mining of a min-difficulty block.
+ if (pblock->nTime > pindexLast->nTime + Params().TargetSpacing()*2)
+ return nProofOfWorkLimit;
+ else
+ {
+ // Return the last non-special-min-difficulty-rules-block
+ const CBlockIndex* pindex = pindexLast;
+ while (pindex->pprev && pindex->nHeight % Params().Interval() != 0 && pindex->nBits == nProofOfWorkLimit)
+ pindex = pindex->pprev;
+ return pindex->nBits;
+ }
+ }
+ return pindexLast->nBits;
+ }
+
+ // Go back by what we want to be 14 days worth of blocks
+ const CBlockIndex* pindexFirst = pindexLast;
+ for (int i = 0; pindexFirst && i < Params().Interval()-1; i++)
+ pindexFirst = pindexFirst->pprev;
+ assert(pindexFirst);
+
+ // Limit adjustment step
+ int64_t nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
+ LogPrintf(" nActualTimespan = %d before bounds\n", nActualTimespan);
+ if (nActualTimespan < Params().TargetTimespan()/4)
+ nActualTimespan = Params().TargetTimespan()/4;
+ if (nActualTimespan > Params().TargetTimespan()*4)
+ nActualTimespan = Params().TargetTimespan()*4;
+
+ // Retarget
+ uint256 bnNew;
+ uint256 bnOld;
+ bnNew.SetCompact(pindexLast->nBits);
+ bnOld = bnNew;
+ bnNew *= nActualTimespan;
+ bnNew /= Params().TargetTimespan();
+
+ if (bnNew > Params().ProofOfWorkLimit())
+ bnNew = Params().ProofOfWorkLimit();
+
+ /// debug print
+ LogPrintf("GetNextWorkRequired RETARGET\n");
+ LogPrintf("Params().TargetTimespan() = %d nActualTimespan = %d\n", Params().TargetTimespan(), nActualTimespan);
+ LogPrintf("Before: %08x %s\n", pindexLast->nBits, bnOld.ToString());
+ LogPrintf("After: %08x %s\n", bnNew.GetCompact(), bnNew.ToString());
+
+ return bnNew.GetCompact();
+}
+
+bool CheckProofOfWork(uint256 hash, unsigned int nBits)
+{
+ bool fNegative;
+ bool fOverflow;
+ uint256 bnTarget;
+ bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
+
+ // Check range
+ if (fNegative || bnTarget == 0 || fOverflow || bnTarget > Params().ProofOfWorkLimit())
+ return error("CheckProofOfWork() : nBits below minimum work");
+
+ // Check proof of work matches claimed amount
+ if (hash > bnTarget)
+ return error("CheckProofOfWork() : hash doesn't match nBits");
+
+ return true;
+}
+
+//
+// minimum amount of work that could possibly be required nTime after
+// minimum work required was nBase
+//
+unsigned int ComputeMinWork(unsigned int nBase, int64_t nTime)
+{
+ const uint256 &bnLimit = Params().ProofOfWorkLimit();
+ // Testnet has min-difficulty blocks
+ // after Params().TargetSpacing()*2 time between blocks:
+ if (Params().AllowMinDifficultyBlocks() && nTime > Params().TargetSpacing()*2)
+ return bnLimit.GetCompact();
+
+ uint256 bnResult;
+ bnResult.SetCompact(nBase);
+ while (nTime > 0 && bnResult < bnLimit)
+ {
+ // Maximum 400% adjustment...
+ bnResult *= 4;
+ // ... in best-case exactly 4-times-normal target time
+ nTime -= Params().TargetTimespan()*4;
+ }
+ if (bnResult > bnLimit)
+ bnResult = bnLimit;
+ return bnResult.GetCompact();
+}
diff --git a/src/pow.h b/src/pow.h
new file mode 100644
index 0000000000..0ce5b48766
--- /dev/null
+++ b/src/pow.h
@@ -0,0 +1,23 @@
+
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_POW_H
+#define BITCOIN_POW_H
+
+#include <stdint.h>
+
+class CBlockIndex;
+class CBlockHeader;
+class uint256;
+
+unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock);
+
+/** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */
+bool CheckProofOfWork(uint256 hash, unsigned int nBits);
+/** Calculate the minimum amount of work a received block needs, without knowing its direct parent */
+unsigned int ComputeMinWork(unsigned int nBase, int64_t nTime);
+
+#endif
diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp
index 2a6d6abc35..a448d5a9a0 100644
--- a/src/qt/askpassphrasedialog.cpp
+++ b/src/qt/askpassphrasedialog.cpp
@@ -37,7 +37,7 @@ AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) :
case Encrypt: // Ask passphrase x2
ui->passLabel1->hide();
ui->passEdit1->hide();
- ui->warningLabel->setText(tr("Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>."));
+ ui->warningLabel->setText(tr("Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>."));
setWindowTitle(tr("Encrypt wallet"));
break;
case Unlock: // Ask passphrase
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index 76dddb103c..89305e9f35 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -546,7 +546,7 @@ int main(int argc, char *argv[])
if (!PaymentServer::ipcParseCommandLine(argc, argv))
exit(0);
#endif
- bool isaTestNet = Params().NetworkID() != CChainParams::MAIN;
+ bool isaTestNet = Params().NetworkID() != CBaseChainParams::MAIN;
// Allow for separate UI settings for testnets
if (isaTestNet)
QApplication::setApplicationName(QAPP_APP_NAME_TESTNET);
diff --git a/src/qt/forms/helpmessagedialog.ui b/src/qt/forms/helpmessagedialog.ui
index d8ab27c238..81dbd90b12 100644
--- a/src/qt/forms/helpmessagedialog.ui
+++ b/src/qt/forms/helpmessagedialog.ui
@@ -60,6 +60,9 @@
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
+ <property name="openExternalLinks">
+ <bool>true</bool>
+ </property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
diff --git a/src/qt/forms/sendcoinsentry.ui b/src/qt/forms/sendcoinsentry.ui
index e77de0d9b8..9d829970f0 100644
--- a/src/qt/forms/sendcoinsentry.ui
+++ b/src/qt/forms/sendcoinsentry.ui
@@ -51,7 +51,7 @@
<item>
<widget class="QValidatedLineEdit" name="payTo">
<property name="toolTip">
- <string>The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</string>
+ <string>The Bitcoin address to send the payment to</string>
</property>
</widget>
</item>
diff --git a/src/qt/forms/signverifymessagedialog.ui b/src/qt/forms/signverifymessagedialog.ui
index aa271b4f2a..53573ec821 100644
--- a/src/qt/forms/signverifymessagedialog.ui
+++ b/src/qt/forms/signverifymessagedialog.ui
@@ -45,7 +45,7 @@
<item>
<widget class="QValidatedLineEdit" name="addressIn_SM">
<property name="toolTip">
- <string>The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</string>
+ <string>The Bitcoin address to sign the message with</string>
</property>
</widget>
</item>
@@ -255,7 +255,7 @@
<item>
<widget class="QValidatedLineEdit" name="addressIn_VM">
<property name="toolTip">
- <string>The address the message was signed with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</string>
+ <string>The Bitcoin address the message was signed with</string>
</property>
</widget>
</item>
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index 4fe98251d9..81b9054252 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -91,7 +91,9 @@ void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent)
widget->setFont(bitcoinAddressFont());
#if QT_VERSION >= 0x040700
- widget->setPlaceholderText(QObject::tr("Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)"));
+ // We don't want translators to use own addresses in translations
+ // and this is the only place, where this address is supplied.
+ widget->setPlaceholderText(QObject::tr("Enter a Bitcoin address (e.g. %1)").arg("1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L"));
#endif
widget->setValidator(new BitcoinAddressEntryValidator(parent));
widget->setCheckValidator(new BitcoinAddressCheckValidator(parent));
diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp
index 49923a1afc..fbb11617fe 100644
--- a/src/qt/paymentserver.cpp
+++ b/src/qt/paymentserver.cpp
@@ -199,10 +199,10 @@ bool PaymentServer::ipcParseCommandLine(int argc, char* argv[])
{
CBitcoinAddress address(r.address.toStdString());
- SelectParams(CChainParams::MAIN);
+ SelectParams(CBaseChainParams::MAIN);
if (!address.IsValid())
{
- SelectParams(CChainParams::TESTNET);
+ SelectParams(CBaseChainParams::TESTNET);
}
}
}
@@ -214,9 +214,9 @@ bool PaymentServer::ipcParseCommandLine(int argc, char* argv[])
if (readPaymentRequest(arg, request))
{
if (request.getDetails().network() == "main")
- SelectParams(CChainParams::MAIN);
+ SelectParams(CBaseChainParams::MAIN);
else
- SelectParams(CChainParams::TESTNET);
+ SelectParams(CBaseChainParams::TESTNET);
}
}
else
diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp
index 3e56412c7c..d4d021e21c 100644
--- a/src/qt/signverifymessagedialog.cpp
+++ b/src/qt/signverifymessagedialog.cpp
@@ -27,7 +27,6 @@ SignVerifyMessageDialog::SignVerifyMessageDialog(QWidget *parent) :
#if QT_VERSION >= 0x040700
ui->signatureOut_SM->setPlaceholderText(tr("Click \"Sign Message\" to generate signature"));
- ui->addressIn_VM->setPlaceholderText(tr("Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)"));
#endif
GUIUtil::setupAddressWidget(ui->addressIn_SM, this);
diff --git a/src/qt/test/paymentservertests.cpp b/src/qt/test/paymentservertests.cpp
index 7dee7a9cda..e92a7d2b1a 100644
--- a/src/qt/test/paymentservertests.cpp
+++ b/src/qt/test/paymentservertests.cpp
@@ -56,6 +56,7 @@ static SendCoinsRecipient handleRequest(PaymentServer* server, std::vector<unsig
void PaymentServerTests::paymentServerTests()
{
+ SelectParams(CBaseChainParams::MAIN);
OptionsModel optionsModel;
PaymentServer* server = new PaymentServer(NULL, false);
X509_STORE* caStore = X509_STORE_new();
diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp
index 61da3373fd..e48dbcac9d 100644
--- a/src/qt/transactiondesc.cpp
+++ b/src/qt/transactiondesc.cpp
@@ -12,6 +12,7 @@
#include "main.h"
#include "paymentserver.h"
#include "transactionrecord.h"
+#include "timedata.h"
#include "ui_interface.h"
#include "wallet.h"
diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp
index 5a3728f498..eec2b57e8c 100644
--- a/src/qt/transactionrecord.cpp
+++ b/src/qt/transactionrecord.cpp
@@ -5,6 +5,7 @@
#include "transactionrecord.h"
#include "base58.h"
+#include "timedata.h"
#include "wallet.h"
#include <stdint.h>
diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp
index 3a06e33016..30881b9b1a 100644
--- a/src/rpcclient.cpp
+++ b/src/rpcclient.cpp
@@ -72,6 +72,8 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri
if (strMethod == "listtransactions" && n > 2) ConvertTo<int64_t>(params[2]);
if (strMethod == "listaccounts" && n > 0) ConvertTo<int64_t>(params[0]);
if (strMethod == "walletpassphrase" && n > 1) ConvertTo<int64_t>(params[1]);
+ if (strMethod == "prioritisetransaction" && n > 1) ConvertTo<double>(params[1]);
+ if (strMethod == "prioritisetransaction" && n > 2) ConvertTo<int64_t>(params[2]);
if (strMethod == "getblocktemplate" && n > 0) ConvertTo<Object>(params[0]);
if (strMethod == "listsinceblock" && n > 1) ConvertTo<int64_t>(params[1]);
if (strMethod == "sendmany" && n > 1) ConvertTo<Object>(params[1]);
diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp
index a1410f0e41..98caf704ee 100644
--- a/src/rpcmining.cpp
+++ b/src/rpcmining.cpp
@@ -9,6 +9,7 @@
#include "net.h"
#include "main.h"
#include "miner.h"
+#include "pow.h"
#ifdef ENABLE_WALLET
#include "db.h"
#include "wallet.h"
@@ -236,7 +237,7 @@ Value getmininginfo(const Array& params, bool fHelp)
obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", -1)));
obj.push_back(Pair("networkhashps", getnetworkhashps(params, false)));
obj.push_back(Pair("pooledtx", (uint64_t)mempool.size()));
- obj.push_back(Pair("testnet", Params().NetworkID() == CChainParams::TESTNET));
+ obj.push_back(Pair("testnet", Params().NetworkID() == CBaseChainParams::TESTNET));
obj.push_back(Pair("chain", Params().NetworkIDString()));
#ifdef ENABLE_WALLET
obj.push_back(Pair("generate", getgenerate(params, false)));
@@ -246,6 +247,20 @@ Value getmininginfo(const Array& params, bool fHelp)
}
+Value prioritisetransaction(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 3)
+ throw runtime_error(
+ "prioritisetransaction <txid> <priority delta> <fee delta>\n"
+ "Accepts the transaction into mined blocks at a higher (or lower) priority");
+
+ uint256 hash;
+ hash.SetHex(params[0].get_str());
+ mempool.PrioritiseTransaction(hash, params[0].get_str(), params[1].get_real(), params[2].get_int64());
+ return true;
+}
+
+
Value getblocktemplate(const Array& params, bool fHelp)
{
if (fHelp || params.size() > 1)
diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp
index 5181aa23d8..5b470516a1 100644
--- a/src/rpcmisc.cpp
+++ b/src/rpcmisc.cpp
@@ -9,6 +9,7 @@
#include "net.h"
#include "netbase.h"
#include "rpcserver.h"
+#include "timedata.h"
#include "util.h"
#ifdef ENABLE_WALLET
#include "wallet.h"
@@ -21,10 +22,10 @@
#include "json/json_spirit_utils.h"
#include "json/json_spirit_value.h"
-using namespace std;
using namespace boost;
using namespace boost::assign;
using namespace json_spirit;
+using namespace std;
Value getinfo(const Array& params, bool fHelp)
{
@@ -73,7 +74,7 @@ Value getinfo(const Array& params, bool fHelp)
obj.push_back(Pair("connections", (int)vNodes.size()));
obj.push_back(Pair("proxy", (proxy.first.IsValid() ? proxy.first.ToStringIPPort() : string())));
obj.push_back(Pair("difficulty", (double)GetDifficulty()));
- obj.push_back(Pair("testnet", Params().NetworkID() == CChainParams::TESTNET));
+ obj.push_back(Pair("testnet", Params().NetworkID() == CBaseChainParams::TESTNET));
#ifdef ENABLE_WALLET
if (pwalletMain) {
obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime()));
diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp
index 6fc86eedfb..a54872ccc4 100644
--- a/src/rpcnet.cpp
+++ b/src/rpcnet.cpp
@@ -9,6 +9,7 @@
#include "netbase.h"
#include "protocol.h"
#include "sync.h"
+#include "timedata.h"
#include "util.h"
#include <boost/foreach.hpp>
diff --git a/src/rpcprotocol.cpp b/src/rpcprotocol.cpp
index 2718f81783..2cb4a35c4b 100644
--- a/src/rpcprotocol.cpp
+++ b/src/rpcprotocol.cpp
@@ -54,7 +54,8 @@ static string rfc1123Time()
return DateTimeStrFormat("%a, %d %b %Y %H:%M:%S +0000", GetTime());
}
-string HTTPReply(int nStatus, const string& strMsg, bool keepalive)
+string HTTPReply(int nStatus, const string& strMsg, bool keepalive,
+ bool headersOnly, const char *contentType)
{
if (nStatus == HTTP_UNAUTHORIZED)
return strprintf("HTTP/1.0 401 Authorization Required\r\n"
@@ -73,6 +74,7 @@ string HTTPReply(int nStatus, const string& strMsg, bool keepalive)
"</HEAD>\r\n"
"<BODY><H1>401 Unauthorized.</H1></BODY>\r\n"
"</HTML>\r\n", rfc1123Time(), FormatFullVersion());
+
const char *cStatus;
if (nStatus == HTTP_OK) cStatus = "OK";
else if (nStatus == HTTP_BAD_REQUEST) cStatus = "Bad Request";
@@ -80,12 +82,19 @@ string HTTPReply(int nStatus, const string& strMsg, bool keepalive)
else if (nStatus == HTTP_NOT_FOUND) cStatus = "Not Found";
else if (nStatus == HTTP_INTERNAL_SERVER_ERROR) cStatus = "Internal Server Error";
else cStatus = "";
+
+ bool useInternalContent = false;
+ if (nStatus != HTTP_OK) {
+ contentType = "text/plain";
+ useInternalContent = true;
+ }
+
return strprintf(
"HTTP/1.1 %d %s\r\n"
"Date: %s\r\n"
"Connection: %s\r\n"
"Content-Length: %u\r\n"
- "Content-Type: application/json\r\n"
+ "Content-Type: %s\r\n"
"Server: bitcoin-json-rpc/%s\r\n"
"\r\n"
"%s",
@@ -94,8 +103,10 @@ string HTTPReply(int nStatus, const string& strMsg, bool keepalive)
rfc1123Time(),
keepalive ? "keep-alive" : "close",
strMsg.size(),
+ contentType,
FormatFullVersion(),
- strMsg);
+ (headersOnly ? "" :
+ (useInternalContent ? cStatus : strMsg.c_str())));
}
bool ReadHTTPRequestLine(std::basic_istream<char>& stream, int &proto,
diff --git a/src/rpcprotocol.h b/src/rpcprotocol.h
index 11bdd171d9..f1317e9c28 100644
--- a/src/rpcprotocol.h
+++ b/src/rpcprotocol.h
@@ -141,7 +141,9 @@ private:
};
std::string HTTPPost(const std::string& strMsg, const std::map<std::string,std::string>& mapRequestHeaders);
-std::string HTTPReply(int nStatus, const std::string& strMsg, bool keepalive);
+std::string HTTPReply(int nStatus, const std::string& strMsg, bool keepalive,
+ bool headerOnly = false,
+ const char *contentType = "application/json");
bool ReadHTTPRequestLine(std::basic_istream<char>& stream, int &proto,
std::string& http_method, std::string& http_uri);
int ReadHTTPStatus(std::basic_istream<char>& stream, int &proto);
diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp
index 93da81e429..54043458d5 100644
--- a/src/rpcserver.cpp
+++ b/src/rpcserver.cpp
@@ -25,10 +25,10 @@
#include <boost/shared_ptr.hpp>
#include "json/json_spirit_writer_template.h"
-using namespace std;
using namespace boost;
using namespace boost::asio;
using namespace json_spirit;
+using namespace std;
static std::string strRPCUserColonPass;
@@ -254,6 +254,7 @@ static const CRPCCommand vRPCCommands[] =
{ "getblocktemplate", &getblocktemplate, true, false, false },
{ "getmininginfo", &getmininginfo, true, false, false },
{ "getnetworkhashps", &getnetworkhashps, true, false, false },
+ { "prioritisetransaction", &prioritisetransaction, true, false, false },
{ "submitblock", &submitblock, false, true, false },
/* Raw transactions */
@@ -392,16 +393,6 @@ bool ClientAllowed(const boost::asio::ip::address& address)
return false;
}
-class AcceptedConnection
-{
-public:
- virtual ~AcceptedConnection() {}
-
- virtual std::iostream& stream() = 0;
- virtual std::string peer_address_to_string() const = 0;
- virtual void close() = 0;
-};
-
template <typename Protocol>
class AcceptedConnectionImpl : public AcceptedConnection
{
@@ -600,7 +591,7 @@ void StartRPCThreads()
std::vector<ip::tcp::endpoint> vEndpoints;
bool bBindAny = false;
- int defaultPort = GetArg("-rpcport", Params().RPCPort());
+ int defaultPort = GetArg("-rpcport", BaseParams().RPCPort());
if (!mapArgs.count("-rpcallowip")) // Default to loopback if not allowing external IPs
{
vEndpoints.push_back(ip::tcp::endpoint(asio::ip::address_v6::loopback(), defaultPort));
@@ -818,6 +809,71 @@ static string JSONRPCExecBatch(const Array& vReq)
return write_string(Value(ret), false) + "\n";
}
+static bool HTTPReq_JSONRPC(AcceptedConnection *conn,
+ string& strRequest,
+ map<string, string>& mapHeaders,
+ bool fRun)
+{
+ // Check authorization
+ if (mapHeaders.count("authorization") == 0)
+ {
+ conn->stream() << HTTPReply(HTTP_UNAUTHORIZED, "", false) << std::flush;
+ return false;
+ }
+
+ if (!HTTPAuthorized(mapHeaders))
+ {
+ LogPrintf("ThreadRPCServer incorrect password attempt from %s\n", conn->peer_address_to_string());
+ /* Deter brute-forcing short passwords.
+ If this results in a DoS the user really
+ shouldn't have their RPC port exposed. */
+ if (mapArgs["-rpcpassword"].size() < 20)
+ MilliSleep(250);
+
+ conn->stream() << HTTPReply(HTTP_UNAUTHORIZED, "", false) << std::flush;
+ return false;
+ }
+
+ JSONRequest jreq;
+ try
+ {
+ // Parse request
+ Value valRequest;
+ if (!read_string(strRequest, valRequest))
+ throw JSONRPCError(RPC_PARSE_ERROR, "Parse error");
+
+ string strReply;
+
+ // singleton request
+ if (valRequest.type() == obj_type) {
+ jreq.parse(valRequest);
+
+ Value result = tableRPC.execute(jreq.strMethod, jreq.params);
+
+ // Send reply
+ strReply = JSONRPCReply(result, Value::null, jreq.id);
+
+ // array of requests
+ } else if (valRequest.type() == array_type)
+ strReply = JSONRPCExecBatch(valRequest.get_array());
+ else
+ throw JSONRPCError(RPC_PARSE_ERROR, "Top-level object parse error");
+
+ conn->stream() << HTTPReply(HTTP_OK, strReply, fRun) << std::flush;
+ }
+ catch (Object& objError)
+ {
+ ErrorReply(conn->stream(), objError, jreq.id);
+ return false;
+ }
+ catch (std::exception& e)
+ {
+ ErrorReply(conn->stream(), JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id);
+ return false;
+ }
+ return true;
+}
+
void ServiceConnection(AcceptedConnection *conn)
{
bool fRun = true;
@@ -834,67 +890,15 @@ void ServiceConnection(AcceptedConnection *conn)
// Read HTTP message headers and body
ReadHTTPMessage(conn->stream(), mapHeaders, strRequest, nProto);
- if (strURI != "/") {
- conn->stream() << HTTPReply(HTTP_NOT_FOUND, "", false) << std::flush;
- break;
- }
-
- // Check authorization
- if (mapHeaders.count("authorization") == 0)
- {
- conn->stream() << HTTPReply(HTTP_UNAUTHORIZED, "", false) << std::flush;
- break;
- }
- if (!HTTPAuthorized(mapHeaders))
- {
- LogPrintf("ThreadRPCServer incorrect password attempt from %s\n", conn->peer_address_to_string());
- /* Deter brute-forcing short passwords.
- If this results in a DoS the user really
- shouldn't have their RPC port exposed. */
- if (mapArgs["-rpcpassword"].size() < 20)
- MilliSleep(250);
-
- conn->stream() << HTTPReply(HTTP_UNAUTHORIZED, "", false) << std::flush;
- break;
- }
+ // HTTP Keep-Alive is false; close connection immediately
if (mapHeaders["connection"] == "close")
fRun = false;
- JSONRequest jreq;
- try
- {
- // Parse request
- Value valRequest;
- if (!read_string(strRequest, valRequest))
- throw JSONRPCError(RPC_PARSE_ERROR, "Parse error");
-
- string strReply;
-
- // singleton request
- if (valRequest.type() == obj_type) {
- jreq.parse(valRequest);
-
- Value result = tableRPC.execute(jreq.strMethod, jreq.params);
-
- // Send reply
- strReply = JSONRPCReply(result, Value::null, jreq.id);
-
- // array of requests
- } else if (valRequest.type() == array_type)
- strReply = JSONRPCExecBatch(valRequest.get_array());
- else
- throw JSONRPCError(RPC_PARSE_ERROR, "Top-level object parse error");
-
- conn->stream() << HTTPReply(HTTP_OK, strReply, fRun) << std::flush;
- }
- catch (Object& objError)
- {
- ErrorReply(conn->stream(), objError, jreq.id);
- break;
- }
- catch (std::exception& e)
- {
- ErrorReply(conn->stream(), JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id);
+ if (strURI == "/") {
+ if (!HTTPReq_JSONRPC(conn, strRequest, mapHeaders, fRun))
+ break;
+ } else {
+ conn->stream() << HTTPReply(HTTP_NOT_FOUND, "", false) << std::flush;
break;
}
}
diff --git a/src/rpcserver.h b/src/rpcserver.h
index 5271542385..fcd293663f 100644
--- a/src/rpcserver.h
+++ b/src/rpcserver.h
@@ -21,6 +21,16 @@
class CBlockIndex;
class CNetAddr;
+class AcceptedConnection
+{
+public:
+ virtual ~AcceptedConnection() {}
+
+ virtual std::iostream& stream() = 0;
+ virtual std::string peer_address_to_string() const = 0;
+ virtual void close() = 0;
+};
+
/* Start RPC threads */
void StartRPCThreads();
/* Alternative to StartRPCThreads for the GUI, when no server is
@@ -130,6 +140,7 @@ extern json_spirit::Value setgenerate(const json_spirit::Array& params, bool fHe
extern json_spirit::Value getnetworkhashps(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value gethashespersec(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value prioritisetransaction(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getblocktemplate(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value submitblock(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value estimatefee(const json_spirit::Array& params, bool fHelp);
diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp
index f376ab6b63..4f27cef087 100644
--- a/src/rpcwallet.cpp
+++ b/src/rpcwallet.cpp
@@ -8,6 +8,7 @@
#include "init.h"
#include "net.h"
#include "netbase.h"
+#include "timedata.h"
#include "util.h"
#include "wallet.h"
#include "walletdb.h"
diff --git a/src/script.cpp b/src/script.cpp
index c83d26885a..bc4705abe7 100644
--- a/src/script.cpp
+++ b/src/script.cpp
@@ -1208,7 +1208,8 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector<vector<unsi
mTemplates.insert(make_pair(TX_MULTISIG, CScript() << OP_SMALLINTEGER << OP_PUBKEYS << OP_SMALLINTEGER << OP_CHECKMULTISIG));
// Empty, provably prunable, data-carrying output
- mTemplates.insert(make_pair(TX_NULL_DATA, CScript() << OP_RETURN << OP_SMALLDATA));
+ if (GetBoolArg("-datacarrier", true))
+ mTemplates.insert(make_pair(TX_NULL_DATA, CScript() << OP_RETURN << OP_SMALLDATA));
mTemplates.insert(make_pair(TX_NULL_DATA, CScript() << OP_RETURN));
}
diff --git a/src/script.h b/src/script.h
index ea988f0e40..7ab471f6e6 100644
--- a/src/script.h
+++ b/src/script.h
@@ -20,7 +20,7 @@
class CCoins;
class CKeyStore;
class CTransaction;
-class CMutableTransaction;
+struct CMutableTransaction;
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520; // bytes
static const unsigned int MAX_OP_RETURN_RELAY = 40; // bytes
diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp
index 3a45844411..5e17555e7a 100644
--- a/src/test/DoS_tests.cpp
+++ b/src/test/DoS_tests.cpp
@@ -11,6 +11,7 @@
#include "keystore.h"
#include "main.h"
#include "net.h"
+#include "pow.h"
#include "script.h"
#include "serialize.h"
@@ -230,91 +231,4 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
BOOST_CHECK(mapOrphanTransactionsByPrev.empty());
}
-BOOST_AUTO_TEST_CASE(DoS_checkSig)
-{
- // Test signature caching code (see key.cpp Verify() methods)
-
- CKey key;
- key.MakeNewKey(true);
- CBasicKeyStore keystore;
- keystore.AddKey(key);
- unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC;
-
- // 100 orphan transactions:
- static const int NPREV=100;
- CMutableTransaction orphans[NPREV];
- for (int i = 0; i < NPREV; i++)
- {
- CMutableTransaction& tx = orphans[i];
- tx.vin.resize(1);
- tx.vin[0].prevout.n = 0;
- tx.vin[0].prevout.hash = GetRandHash();
- tx.vin[0].scriptSig << OP_1;
- tx.vout.resize(1);
- tx.vout[0].nValue = 1*CENT;
- tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID());
-
- AddOrphanTx(tx);
- }
-
- // Create a transaction that depends on orphans:
- CMutableTransaction tx;
- tx.vout.resize(1);
- tx.vout[0].nValue = 1*CENT;
- tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID());
- tx.vin.resize(NPREV);
- for (unsigned int j = 0; j < tx.vin.size(); j++)
- {
- tx.vin[j].prevout.n = 0;
- tx.vin[j].prevout.hash = orphans[j].GetHash();
- }
- // Creating signatures primes the cache:
- boost::posix_time::ptime mst1 = boost::posix_time::microsec_clock::local_time();
- for (unsigned int j = 0; j < tx.vin.size(); j++)
- BOOST_CHECK(SignSignature(keystore, orphans[j], tx, j));
- boost::posix_time::ptime mst2 = boost::posix_time::microsec_clock::local_time();
- boost::posix_time::time_duration msdiff = mst2 - mst1;
- long nOneValidate = msdiff.total_milliseconds();
- if (fDebug) printf("DoS_Checksig sign: %ld\n", nOneValidate);
-
- // ... now validating repeatedly should be quick:
- // 2.8GHz machine, -g build: Sign takes ~760ms,
- // uncached Verify takes ~250ms, cached Verify takes ~50ms
- // (for 100 single-signature inputs)
- mst1 = boost::posix_time::microsec_clock::local_time();
- for (unsigned int i = 0; i < 5; i++)
- for (unsigned int j = 0; j < tx.vin.size(); j++)
- BOOST_CHECK(VerifySignature(CCoins(orphans[j], MEMPOOL_HEIGHT), tx, j, flags, SIGHASH_ALL));
- mst2 = boost::posix_time::microsec_clock::local_time();
- msdiff = mst2 - mst1;
- long nManyValidate = msdiff.total_milliseconds();
- if (fDebug) printf("DoS_Checksig five: %ld\n", nManyValidate);
-
- BOOST_CHECK_MESSAGE(nManyValidate < nOneValidate, "Signature cache timing failed");
-
- // Empty a signature, validation should fail:
- CScript save = tx.vin[0].scriptSig;
- tx.vin[0].scriptSig = CScript();
- BOOST_CHECK(!VerifySignature(CCoins(orphans[0], MEMPOOL_HEIGHT), tx, 0, flags, SIGHASH_ALL));
- tx.vin[0].scriptSig = save;
-
- // Swap signatures, validation should fail:
- std::swap(tx.vin[0].scriptSig, tx.vin[1].scriptSig);
- BOOST_CHECK(!VerifySignature(CCoins(orphans[0], MEMPOOL_HEIGHT), tx, 0, flags, SIGHASH_ALL));
- BOOST_CHECK(!VerifySignature(CCoins(orphans[1], MEMPOOL_HEIGHT), tx, 1, flags, SIGHASH_ALL));
- std::swap(tx.vin[0].scriptSig, tx.vin[1].scriptSig);
-
- // Exercise -maxsigcachesize code:
- mapArgs["-maxsigcachesize"] = "10";
- // Generate a new, different signature for vin[0] to trigger cache clear:
- CScript oldSig = tx.vin[0].scriptSig;
- BOOST_CHECK(SignSignature(keystore, orphans[0], tx, 0));
- BOOST_CHECK(tx.vin[0].scriptSig != oldSig);
- for (unsigned int j = 0; j < tx.vin.size(); j++)
- BOOST_CHECK(VerifySignature(CCoins(orphans[j], MEMPOOL_HEIGHT), tx, j, flags, SIGHASH_ALL));
- mapArgs.erase("-maxsigcachesize");
-
- LimitOrphanTxSize(0);
-}
-
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp
index b81a19cfd8..0ac3e9a363 100644
--- a/src/test/base58_tests.cpp
+++ b/src/test/base58_tests.cpp
@@ -142,9 +142,9 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse)
bool isPrivkey = find_value(metadata, "isPrivkey").get_bool();
bool isTestnet = find_value(metadata, "isTestnet").get_bool();
if (isTestnet)
- SelectParams(CChainParams::TESTNET);
+ SelectParams(CBaseChainParams::TESTNET);
else
- SelectParams(CChainParams::MAIN);
+ SelectParams(CBaseChainParams::MAIN);
if(isPrivkey)
{
bool isCompressed = find_value(metadata, "isCompressed").get_bool();
@@ -175,7 +175,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse)
BOOST_CHECK_MESSAGE(!secret.IsValid(), "IsValid pubkey as privkey:" + strTest);
}
}
- SelectParams(CChainParams::MAIN);
+ SelectParams(CBaseChainParams::MAIN);
}
// Goal: check that generated keys match test vectors
@@ -198,9 +198,9 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen)
bool isPrivkey = find_value(metadata, "isPrivkey").get_bool();
bool isTestnet = find_value(metadata, "isTestnet").get_bool();
if (isTestnet)
- SelectParams(CChainParams::TESTNET);
+ SelectParams(CBaseChainParams::TESTNET);
else
- SelectParams(CChainParams::MAIN);
+ SelectParams(CBaseChainParams::MAIN);
if(isPrivkey)
{
bool isCompressed = find_value(metadata, "isCompressed").get_bool();
@@ -243,7 +243,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen)
CTxDestination nodest = CNoDestination();
BOOST_CHECK(!dummyAddr.Set(nodest));
- SelectParams(CChainParams::MAIN);
+ SelectParams(CBaseChainParams::MAIN);
}
// Goal: check that base58 parsing code is robust against a variety of corrupted data
diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp
index 2d993e24db..8cae0a4c34 100644
--- a/src/test/test_bitcoin.cpp
+++ b/src/test/test_bitcoin.cpp
@@ -31,6 +31,7 @@ struct TestingSetup {
TestingSetup() {
fPrintToDebugLog = false; // don't want to write to debug.log file
+ SelectParams(CBaseChainParams::MAIN);
noui_connect();
#ifdef ENABLE_WALLET
bitdb.MakeMock();
diff --git a/src/timedata.cpp b/src/timedata.cpp
new file mode 100644
index 0000000000..8a095d26dc
--- /dev/null
+++ b/src/timedata.cpp
@@ -0,0 +1,91 @@
+// Copyright (c) 2014 The Bitcoin developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "timedata.h"
+
+#include "netbase.h"
+#include "sync.h"
+#include "ui_interface.h"
+#include "util.h"
+
+#include <boost/foreach.hpp>
+
+using namespace std;
+
+static CCriticalSection cs_nTimeOffset;
+static int64_t nTimeOffset = 0;
+
+//
+// "Never go to sea with two chronometers; take one or three."
+// Our three time sources are:
+// - System clock
+// - Median of other nodes clocks
+// - The user (asking the user to fix the system clock if the first two disagree)
+//
+//
+int64_t GetTimeOffset()
+{
+ LOCK(cs_nTimeOffset);
+ return nTimeOffset;
+}
+
+int64_t GetAdjustedTime()
+{
+ return GetTime() + GetTimeOffset();
+}
+
+void AddTimeData(const CNetAddr& ip, int64_t nTime)
+{
+ int64_t nOffsetSample = nTime - GetTime();
+
+ LOCK(cs_nTimeOffset);
+ // Ignore duplicates
+ static set<CNetAddr> setKnown;
+ if (!setKnown.insert(ip).second)
+ return;
+
+ // Add data
+ static CMedianFilter<int64_t> vTimeOffsets(200,0);
+ vTimeOffsets.input(nOffsetSample);
+ LogPrintf("Added time data, samples %d, offset %+d (%+d minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60);
+ if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1)
+ {
+ int64_t nMedian = vTimeOffsets.median();
+ std::vector<int64_t> vSorted = vTimeOffsets.sorted();
+ // Only let other nodes change our time by so much
+ if (abs64(nMedian) < 70 * 60)
+ {
+ nTimeOffset = nMedian;
+ }
+ else
+ {
+ nTimeOffset = 0;
+
+ static bool fDone;
+ if (!fDone)
+ {
+ // If nobody has a time different than ours but within 5 minutes of ours, give a warning
+ bool fMatch = false;
+ BOOST_FOREACH(int64_t nOffset, vSorted)
+ if (nOffset != 0 && abs64(nOffset) < 5 * 60)
+ fMatch = true;
+
+ if (!fMatch)
+ {
+ fDone = true;
+ string strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin will not work properly.");
+ strMiscWarning = strMessage;
+ LogPrintf("*** %s\n", strMessage);
+ uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING);
+ }
+ }
+ }
+ if (fDebug) {
+ BOOST_FOREACH(int64_t n, vSorted)
+ LogPrintf("%+d ", n);
+ LogPrintf("| ");
+ }
+ LogPrintf("nTimeOffset = %+d (%+d minutes)\n", nTimeOffset, nTimeOffset/60);
+ }
+}
diff --git a/src/timedata.h b/src/timedata.h
new file mode 100644
index 0000000000..0e7bdc2c1f
--- /dev/null
+++ b/src/timedata.h
@@ -0,0 +1,17 @@
+// Copyright (c) 2014 The Bitcoin developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_TIMEDATA_H
+#define BITCOIN_TIMEDATA_H
+
+#include <stdint.h>
+
+class CNetAddr;
+
+/* Functions to keep track of adjusted P2P time */
+int64_t GetTimeOffset();
+int64_t GetAdjustedTime();
+void AddTimeData(const CNetAddr& ip, int64_t nTime);
+
+#endif
diff --git a/src/txdb.cpp b/src/txdb.cpp
index 4eab8525a5..92137f71ff 100644
--- a/src/txdb.cpp
+++ b/src/txdb.cpp
@@ -6,6 +6,7 @@
#include "txdb.h"
#include "core.h"
+#include "pow.h"
#include "uint256.h"
#include <stdint.h>
@@ -212,8 +213,8 @@ bool CBlockTreeDB::LoadBlockIndexGuts()
pindexNew->nStatus = diskindex.nStatus;
pindexNew->nTx = diskindex.nTx;
- if (!pindexNew->CheckIndex())
- return error("LoadBlockIndex() : CheckIndex failed: %s", pindexNew->ToString());
+ if (!CheckProofOfWork(pindexNew->GetBlockHash(), pindexNew->nBits))
+ return error("LoadBlockIndex() : CheckProofOfWork failed: %s", pindexNew->ToString());
pcursor->Next();
} else {
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index 4bf01d4848..52f82ef040 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -447,6 +447,7 @@ void CTxMemPool::removeForBlock(const std::vector<CTransaction>& vtx, unsigned i
std::list<CTransaction> dummy;
remove(tx, dummy, false);
removeConflicts(tx, conflicts);
+ ClearPrioritisation(tx.GetHash());
}
}
@@ -564,6 +565,34 @@ CTxMemPool::ReadFeeEstimates(CAutoFile& filein)
return true;
}
+void CTxMemPool::PrioritiseTransaction(const uint256 hash, const string strHash, double dPriorityDelta, int64_t nFeeDelta)
+{
+ {
+ LOCK(cs);
+ std::pair<double, int64_t> &deltas = mapDeltas[hash];
+ deltas.first += dPriorityDelta;
+ deltas.second += nFeeDelta;
+ }
+ LogPrintf("PrioritiseTransaction: %s priority += %f, fee += %d\n", strHash.c_str(), dPriorityDelta, nFeeDelta);
+}
+
+void CTxMemPool::ApplyDeltas(const uint256 hash, double &dPriorityDelta, int64_t &nFeeDelta)
+{
+ LOCK(cs);
+ std::map<uint256, std::pair<double, int64_t> >::iterator pos = mapDeltas.find(hash);
+ if (pos == mapDeltas.end())
+ return;
+ const std::pair<double, int64_t> &deltas = pos->second;
+ dPriorityDelta += deltas.first;
+ nFeeDelta += deltas.second;
+}
+
+void CTxMemPool::ClearPrioritisation(const uint256 hash)
+{
+ LOCK(cs);
+ mapDeltas.erase(hash);
+}
+
CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView &baseIn, CTxMemPool &mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { }
diff --git a/src/txmempool.h b/src/txmempool.h
index b2915aa842..f7dbb126a0 100644
--- a/src/txmempool.h
+++ b/src/txmempool.h
@@ -71,6 +71,7 @@ public:
mutable CCriticalSection cs;
std::map<uint256, CTxMemPoolEntry> mapTx;
std::map<COutPoint, CInPoint> mapNextTx;
+ std::map<uint256, std::pair<double, int64_t> > mapDeltas;
CTxMemPool();
~CTxMemPool();
@@ -95,6 +96,11 @@ public:
unsigned int GetTransactionsUpdated() const;
void AddTransactionsUpdated(unsigned int n);
+ /** Affect CreateNewBlock prioritisation of transactions */
+ void PrioritiseTransaction(const uint256 hash, const std::string strHash, double dPriorityDelta, int64_t nFeeDelta);
+ void ApplyDeltas(const uint256 hash, double &dPriorityDelta, int64_t &nFeeDelta);
+ void ClearPrioritisation(const uint256 hash);
+
unsigned long size()
{
LOCK(cs);
diff --git a/src/util.cpp b/src/util.cpp
index 30590912ff..9e4b2b787e 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -5,8 +5,7 @@
#include "util.h"
-#include "chainparams.h"
-#include "netbase.h"
+#include "chainparamsbase.h"
#include "sync.h"
#include "ui_interface.h"
#include "uint256.h"
@@ -168,16 +167,31 @@ void RandAddSeedPerfmon()
#ifdef WIN32
// Don't need this on Linux, OpenSSL automatically uses /dev/urandom
// Seed with the entire set of perfmon data
- unsigned char pdata[250000];
- memset(pdata, 0, sizeof(pdata));
- unsigned long nSize = sizeof(pdata);
- long ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize);
+ std::vector <unsigned char> vData(250000,0);
+ long ret = 0;
+ unsigned long nSize = 0;
+ const size_t nMaxSize = 10000000; // Bail out at more than 10MB of performance data
+ while (true)
+ {
+ nSize = vData.size();
+ ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, begin_ptr(vData), &nSize);
+ if (ret != ERROR_MORE_DATA || vData.size() >= nMaxSize)
+ break;
+ vData.resize(std::max((vData.size()*3)/2, nMaxSize)); // Grow size of buffer exponentially
+ }
RegCloseKey(HKEY_PERFORMANCE_DATA);
if (ret == ERROR_SUCCESS)
{
- RAND_add(pdata, nSize, nSize/100.0);
- OPENSSL_cleanse(pdata, nSize);
- LogPrint("rand", "RandAddSeed() %lu bytes\n", nSize);
+ RAND_add(begin_ptr(vData), nSize, nSize/100.0);
+ OPENSSL_cleanse(begin_ptr(vData), nSize);
+ LogPrint("rand", "%s: %lu bytes\n", __func__, nSize);
+ } else {
+ static bool warned = false; // Warn only once
+ if (!warned)
+ {
+ LogPrintf("%s: Warning: RegQueryValueExA(HKEY_PERFORMANCE_DATA) failed with code %i\n", __func__, ret);
+ warned = true;
+ }
}
#endif
}
@@ -919,7 +933,7 @@ boost::filesystem::path GetDefaultDataDir()
#endif
}
-static boost::filesystem::path pathCached[CChainParams::MAX_NETWORK_TYPES+1];
+static boost::filesystem::path pathCached[CBaseChainParams::MAX_NETWORK_TYPES+1];
static CCriticalSection csPathCached;
const boost::filesystem::path &GetDataDir(bool fNetSpecific)
@@ -928,8 +942,8 @@ const boost::filesystem::path &GetDataDir(bool fNetSpecific)
LOCK(csPathCached);
- int nNet = CChainParams::MAX_NETWORK_TYPES;
- if (fNetSpecific) nNet = Params().NetworkID();
+ int nNet = CBaseChainParams::MAX_NETWORK_TYPES;
+ if (fNetSpecific) nNet = BaseParams().NetworkID();
fs::path &path = pathCached[nNet];
@@ -948,7 +962,7 @@ const boost::filesystem::path &GetDataDir(bool fNetSpecific)
path = GetDefaultDataDir();
}
if (fNetSpecific)
- path /= Params().DataDir();
+ path /= BaseParams().DataDir();
fs::create_directories(path);
@@ -957,7 +971,7 @@ const boost::filesystem::path &GetDataDir(bool fNetSpecific)
void ClearDatadirCache()
{
- std::fill(&pathCached[0], &pathCached[CChainParams::MAX_NETWORK_TYPES+1],
+ std::fill(&pathCached[0], &pathCached[CBaseChainParams::MAX_NETWORK_TYPES+1],
boost::filesystem::path());
}
@@ -1141,15 +1155,15 @@ void ShrinkDebugFile()
if (file && boost::filesystem::file_size(pathLog) > 10 * 1000000)
{
// Restart the file with some of the end
- char pch[200000];
- fseek(file, -sizeof(pch), SEEK_END);
- int nBytes = fread(pch, 1, sizeof(pch), file);
+ std::vector <char> vch(200000,0);
+ fseek(file, -vch.size(), SEEK_END);
+ int nBytes = fread(begin_ptr(vch), 1, vch.size(), file);
fclose(file);
file = fopen(pathLog.string().c_str(), "w");
if (file)
{
- fwrite(pch, 1, nBytes, file);
+ fwrite(begin_ptr(vch), 1, nBytes, file);
fclose(file);
}
}
@@ -1157,13 +1171,6 @@ void ShrinkDebugFile()
fclose(file);
}
-//
-// "Never go to sea with two chronometers; take one or three."
-// Our three time sources are:
-// - System clock
-// - Median of other nodes clocks
-// - The user (asking the user to fix the system clock if the first two disagree)
-//
static int64_t nMockTime = 0; // For unit testing
int64_t GetTime()
@@ -1178,75 +1185,6 @@ void SetMockTime(int64_t nMockTimeIn)
nMockTime = nMockTimeIn;
}
-static CCriticalSection cs_nTimeOffset;
-static int64_t nTimeOffset = 0;
-
-int64_t GetTimeOffset()
-{
- LOCK(cs_nTimeOffset);
- return nTimeOffset;
-}
-
-int64_t GetAdjustedTime()
-{
- return GetTime() + GetTimeOffset();
-}
-
-void AddTimeData(const CNetAddr& ip, int64_t nTime)
-{
- int64_t nOffsetSample = nTime - GetTime();
-
- LOCK(cs_nTimeOffset);
- // Ignore duplicates
- static set<CNetAddr> setKnown;
- if (!setKnown.insert(ip).second)
- return;
-
- // Add data
- static CMedianFilter<int64_t> vTimeOffsets(200,0);
- vTimeOffsets.input(nOffsetSample);
- LogPrintf("Added time data, samples %d, offset %+d (%+d minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60);
- if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1)
- {
- int64_t nMedian = vTimeOffsets.median();
- std::vector<int64_t> vSorted = vTimeOffsets.sorted();
- // Only let other nodes change our time by so much
- if (abs64(nMedian) < 70 * 60)
- {
- nTimeOffset = nMedian;
- }
- else
- {
- nTimeOffset = 0;
-
- static bool fDone;
- if (!fDone)
- {
- // If nobody has a time different than ours but within 5 minutes of ours, give a warning
- bool fMatch = false;
- BOOST_FOREACH(int64_t nOffset, vSorted)
- if (nOffset != 0 && abs64(nOffset) < 5 * 60)
- fMatch = true;
-
- if (!fMatch)
- {
- fDone = true;
- string strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin will not work properly.");
- strMiscWarning = strMessage;
- LogPrintf("*** %s\n", strMessage);
- uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING);
- }
- }
- }
- if (fDebug) {
- BOOST_FOREACH(int64_t n, vSorted)
- LogPrintf("%+d ", n);
- LogPrintf("| ");
- }
- LogPrintf("nTimeOffset = %+d (%+d minutes)\n", nTimeOffset, nTimeOffset/60);
- }
-}
-
uint32_t insecure_rand_Rz = 11;
uint32_t insecure_rand_Rw = 11;
void seed_insecure_rand(bool fDeterministic)
diff --git a/src/util.h b/src/util.h
index 5eb6f03826..6057c72e66 100644
--- a/src/util.h
+++ b/src/util.h
@@ -32,7 +32,6 @@
#include <boost/filesystem/path.hpp>
#include <boost/thread.hpp>
-class CNetAddr;
class uint256;
static const int64_t COIN = 100000000;
@@ -191,11 +190,8 @@ uint64_t GetRand(uint64_t nMax);
uint256 GetRandHash();
int64_t GetTime();
void SetMockTime(int64_t nMockTimeIn);
-int64_t GetAdjustedTime();
-int64_t GetTimeOffset();
std::string FormatFullVersion();
std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector<std::string>& comments);
-void AddTimeData(const CNetAddr& ip, int64_t nTime);
void runCommand(std::string strCommand);
diff --git a/src/wallet.cpp b/src/wallet.cpp
index 7664d6c25c..f6fd6e958d 100644
--- a/src/wallet.cpp
+++ b/src/wallet.cpp
@@ -9,6 +9,7 @@
#include "checkpoints.h"
#include "coincontrol.h"
#include "net.h"
+#include "timedata.h"
#include <boost/algorithm/string/replace.hpp>
#include <openssl/rand.h>
@@ -1514,11 +1515,11 @@ DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
}
-DBErrors CWallet::ZapWalletTx()
+DBErrors CWallet::ZapWalletTx(std::vector<CWalletTx>& vWtx)
{
if (!fFileBacked)
return DB_LOAD_OK;
- DBErrors nZapWalletTxRet = CWalletDB(strWalletFile,"cr+").ZapWalletTx(this);
+ DBErrors nZapWalletTxRet = CWalletDB(strWalletFile,"cr+").ZapWalletTx(this, vWtx);
if (nZapWalletTxRet == DB_NEED_REWRITE)
{
if (CDB::Rewrite(strWalletFile, "\x04pool"))
diff --git a/src/wallet.h b/src/wallet.h
index 424799b14e..8494ce9a34 100644
--- a/src/wallet.h
+++ b/src/wallet.h
@@ -341,7 +341,7 @@ public:
void SetBestChain(const CBlockLocator& loc);
DBErrors LoadWallet(bool& fFirstRunRet);
- DBErrors ZapWalletTx();
+ DBErrors ZapWalletTx(std::vector<CWalletTx>& vWtx);
bool SetAddressBook(const CTxDestination& address, const std::string& strName, const std::string& purpose);
diff --git a/src/walletdb.cpp b/src/walletdb.cpp
index 80e9dded5f..3ce2ef019c 100644
--- a/src/walletdb.cpp
+++ b/src/walletdb.cpp
@@ -680,7 +680,7 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet)
return result;
}
-DBErrors CWalletDB::FindWalletTx(CWallet* pwallet, vector<uint256>& vTxHash)
+DBErrors CWalletDB::FindWalletTx(CWallet* pwallet, vector<uint256>& vTxHash, vector<CWalletTx>& vWtx)
{
pwallet->vchDefaultKey = CPubKey();
CWalletScanState wss;
@@ -725,7 +725,11 @@ DBErrors CWalletDB::FindWalletTx(CWallet* pwallet, vector<uint256>& vTxHash)
uint256 hash;
ssKey >> hash;
+ CWalletTx wtx;
+ ssValue >> wtx;
+
vTxHash.push_back(hash);
+ vWtx.push_back(wtx);
}
}
pcursor->close();
@@ -743,11 +747,11 @@ DBErrors CWalletDB::FindWalletTx(CWallet* pwallet, vector<uint256>& vTxHash)
return result;
}
-DBErrors CWalletDB::ZapWalletTx(CWallet* pwallet)
+DBErrors CWalletDB::ZapWalletTx(CWallet* pwallet, vector<CWalletTx>& vWtx)
{
// build list of wallet TXs
vector<uint256> vTxHash;
- DBErrors err = FindWalletTx(pwallet, vTxHash);
+ DBErrors err = FindWalletTx(pwallet, vTxHash, vWtx);
if (err != DB_LOAD_OK)
return err;
diff --git a/src/walletdb.h b/src/walletdb.h
index 3bfb436050..8eb716acbb 100644
--- a/src/walletdb.h
+++ b/src/walletdb.h
@@ -122,8 +122,8 @@ public:
DBErrors ReorderTransactions(CWallet*);
DBErrors LoadWallet(CWallet* pwallet);
- DBErrors FindWalletTx(CWallet* pwallet, std::vector<uint256>& vTxHash);
- DBErrors ZapWalletTx(CWallet* pwallet);
+ DBErrors FindWalletTx(CWallet* pwallet, std::vector<uint256>& vTxHash, std::vector<CWalletTx>& vWtx);
+ DBErrors ZapWalletTx(CWallet* pwallet, std::vector<CWalletTx>& vWtx);
static bool Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys);
static bool Recover(CDBEnv& dbenv, std::string filename);
};