Introduce a CChainParameters singleton class and regtest mode.

The new class is accessed via the Params() method and holds
most things that vary between main, test and regtest networks.
The regtest mode has two purposes, one is to run the
bitcoind/bitcoinj comparison tool which compares two separate
implementations of the Bitcoin protocol looking for divergence.

The other is that when run, you get a local node which can mine
a single block instantly, which is highly convenient for testing
apps during development as there's no need to wait 10 minutes for
a block on the testnet.
This commit is contained in:
Mike Hearn 2013-05-07 15:16:25 +02:00
parent 70e7fba06d
commit 0e4b317555
27 changed files with 540 additions and 571 deletions

View file

@ -147,6 +147,7 @@ HEADERS += src/qt/bitcoingui.h \
src/addrman.h \ src/addrman.h \
src/base58.h \ src/base58.h \
src/bignum.h \ src/bignum.h \
src/chainparams.h \
src/checkpoints.h \ src/checkpoints.h \
src/compat.h \ src/compat.h \
src/sync.h \ src/sync.h \
@ -227,6 +228,7 @@ SOURCES += src/qt/bitcoin.cpp \
src/qt/editaddressdialog.cpp \ src/qt/editaddressdialog.cpp \
src/qt/bitcoinaddressvalidator.cpp \ src/qt/bitcoinaddressvalidator.cpp \
src/alert.cpp \ src/alert.cpp \
src/chainparams.cpp \
src/version.cpp \ src/version.cpp \
src/sync.cpp \ src/sync.cpp \
src/util.cpp \ src/util.cpp \

View file

@ -1,196 +0,0 @@
diff --git a/contrib/test-patches/bitcoind-comparison.patch b/contrib/test-patches/bitcoind-comparison.patch
index 04a8618..519429a 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -31,8 +31,8 @@ CTxMemPool mempool;
map<uint256, CBlockIndex*> mapBlockIndex;
std::vector<CBlockIndex*> vBlockIndexByHeight;
-uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f");
-static CBigNum bnProofOfWorkLimit(~uint256(0) >> 32);
+uint256 hashGenesisBlock("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206");
+static CBigNum bnProofOfWorkLimit(~uint256(0) >> 1);
CBlockIndex* pindexGenesisBlock = NULL;
int nBestHeight = -1;
uint256 nBestChainWork = 0;
@@ -1055,7 +1055,7 @@ int64 static GetBlockValue(int nHeight, int64 nFees)
int64 nSubsidy = 50 * COIN;
// Subsidy is cut in half every 210000 blocks, which will occur approximately every 4 years
- nSubsidy >>= (nHeight / 210000);
+ nSubsidy >>= (nHeight / 150);
return nSubsidy + nFees;
}
@@ -2736,9 +2736,9 @@ bool InitBlockIndex() {
block.hashPrevBlock = 0;
block.hashMerkleRoot = block.BuildMerkleTree();
block.nVersion = 1;
- block.nTime = 1231006505;
- block.nBits = 0x1d00ffff;
- block.nNonce = 2083236893;
+ block.nTime = 1296688602;
+ block.nBits = 0x207fffff;
+ block.nNonce = 2;
if (fTestNet)
{
@@ -3024,7 +3024,7 @@ bool static AlreadyHave(const CInv& inv)
// 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
// a large 4-byte int at any alignment.
-unsigned char pchMessageStart[4] = { 0xf9, 0xbe, 0xb4, 0xd9 };
+unsigned char pchMessageStart[4] = { 0xfa, 0xbf, 0xb5, 0xda };
void static ProcessGetData(CNode* pfrom)
diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp
index af28465..ee9a4db 100644
--- a/src/test/miner_tests.cpp
+++ b/src/test/miner_tests.cpp
@@ -15,34 +15,117 @@ struct {
unsigned char extranonce;
unsigned int nonce;
} blockinfo[] = {
- {4, 0xa4a3e223}, {2, 0x15c32f9e}, {1, 0x0375b547}, {1, 0x7004a8a5},
- {2, 0xce440296}, {2, 0x52cfe198}, {1, 0x77a72cd0}, {2, 0xbb5d6f84},
- {2, 0x83f30c2c}, {1, 0x48a73d5b}, {1, 0xef7dcd01}, {2, 0x6809c6c4},
- {2, 0x0883ab3c}, {1, 0x087bbbe2}, {2, 0x2104a814}, {2, 0xdffb6daa},
- {1, 0xee8a0a08}, {2, 0xba4237c1}, {1, 0xa70349dc}, {1, 0x344722bb},
- {3, 0xd6294733}, {2, 0xec9f5c94}, {2, 0xca2fbc28}, {1, 0x6ba4f406},
- {2, 0x015d4532}, {1, 0x6e119b7c}, {2, 0x43e8f314}, {2, 0x27962f38},
- {2, 0xb571b51b}, {2, 0xb36bee23}, {2, 0xd17924a8}, {2, 0x6bc212d9},
- {1, 0x630d4948}, {2, 0x9a4c4ebb}, {2, 0x554be537}, {1, 0xd63ddfc7},
- {2, 0xa10acc11}, {1, 0x759a8363}, {2, 0xfb73090d}, {1, 0xe82c6a34},
- {1, 0xe33e92d7}, {3, 0x658ef5cb}, {2, 0xba32ff22}, {5, 0x0227a10c},
- {1, 0xa9a70155}, {5, 0xd096d809}, {1, 0x37176174}, {1, 0x830b8d0f},
- {1, 0xc6e3910e}, {2, 0x823f3ca8}, {1, 0x99850849}, {1, 0x7521fb81},
- {1, 0xaacaabab}, {1, 0xd645a2eb}, {5, 0x7aea1781}, {5, 0x9d6e4b78},
- {1, 0x4ce90fd8}, {1, 0xabdc832d}, {6, 0x4a34f32a}, {2, 0xf2524c1c},
- {2, 0x1bbeb08a}, {1, 0xad47f480}, {1, 0x9f026aeb}, {1, 0x15a95049},
- {2, 0xd1cb95b2}, {2, 0xf84bbda5}, {1, 0x0fa62cd1}, {1, 0xe05f9169},
- {1, 0x78d194a9}, {5, 0x3e38147b}, {5, 0x737ba0d4}, {1, 0x63378e10},
- {1, 0x6d5f91cf}, {2, 0x88612eb8}, {2, 0xe9639484}, {1, 0xb7fabc9d},
- {2, 0x19b01592}, {1, 0x5a90dd31}, {2, 0x5bd7e028}, {2, 0x94d00323},
- {1, 0xa9b9c01a}, {1, 0x3a40de61}, {1, 0x56e7eec7}, {5, 0x859f7ef6},
- {1, 0xfd8e5630}, {1, 0x2b0c9f7f}, {1, 0xba700e26}, {1, 0x7170a408},
- {1, 0x70de86a8}, {1, 0x74d64cd5}, {1, 0x49e738a1}, {2, 0x6910b602},
- {0, 0x643c565f}, {1, 0x54264b3f}, {2, 0x97ea6396}, {2, 0x55174459},
- {2, 0x03e8779a}, {1, 0x98f34d8f}, {1, 0xc07b2b07}, {1, 0xdfe29668},
- {1, 0x3141c7c1}, {1, 0xb3b595f4}, {1, 0x735abf08}, {5, 0x623bfbce},
- {2, 0xd351e722}, {1, 0xf4ca48c9}, {1, 0x5b19c670}, {1, 0xa164bf0e},
- {2, 0xbbbeb305}, {2, 0xfe1c810a},
+{4, 2762203683},
+{2, 365113248},
+{1, 58045772},
+{1, 1879353512},
+{2, 3460563607},
+{2, 1389355416},
+{1, 2007444690},
+{2, 3143462790},
+{2, 2213743660},
+{1, 1218919771},
+{1, 4017999107},
+{2, 1745471173},
+{2, 142846780},
+{1, 142326754},
+{2, 553953301},
+{2, 3757796778},
+{1, 4002023946},
+{2, 3124901826},
+{1, 2802010589},
+{1, 877077181},
+{3, 3593029427},
+{2, 3969866902},
+{2, 3392125996},
+{1, 1805972490},
+{2, 22889779},
+{1, 1846647676},
+{2, 1139340052},
+{2, 664153912},
+{2, 3044128027},
+{2, 3010194979},
+{2, 3514377385},
+{2, 1807880922},
+{1, 1661815113},
+{2, 2588692156},
+{2, 1431037239},
+{1, 3594379210},
+{2, 2701839377},
+{1, 1973060452},
+{2, 4218620174},
+{1, 3895224884},
+{1, 3812528857},
+{3, 1703867851},
+{2, 3123904294},
+{5, 36151564},
+{1, 2846294357},
+{5, 3499546633},
+{1, 924279160},
+{1, 2198572304},
+{1, 3336802574},
+{2, 2185182379},
+{1, 2575632458},
+{1, 1965161345},
+{1, 2865408940},
+{1, 3594887915},
+{5, 2062161796},
+{5, 2641251194},
+{1, 1290342362},
+{1, 2883355438},
+{6, 1244984107},
+{2, 4065479712},
+{2, 465481866},
+{1, 2907174016},
+{1, 2667735788},
+{1, 363417673},
+{2, 3519780275},
+{2, 4165713317},
+{1, 262548689},
+{1, 3764359529},
+{1, 2027001003},
+{5, 1043862655},
+{5, 1937481940},
+{1, 1664585233},
+{1, 1834979792},
+{2, 2288070330},
+{2, 3915617412},
+{1, 3086662813},
+{2, 430970259},
+{1, 1519443249},
+{2, 1540874280},
+{2, 2496660261},
+{1, 2847522842},
+{1, 977329763},
+{1, 1458040519},
+{5, 2241822454},
+{1, 4253963824},
+{1, 722247551},
+{1, 3127905834},
+{1, 1903207432},
+{1, 1893631657},
+{1, 1960201429},
+{1, 1239890082},
+{2, 1762702850},
+{0, 1681675873},
+{1, 1411795775},
+{2, 2548720534},
+{2, 1427588186},
+{2, 65566621},
+{1, 2566081936},
+{1, 3229297415},
+{1, 3756168812},
+{1, 826394561},
+{1, 3015022068},
+{1, 1935326986},
+{5, 1648098256},
+{2, 3545360164},
+{1, 4106897609},
+{1, 1528415857},
+{1, 2707734286},
+{2, 3149837061},
+{2, 4263280906},
+
};
// NOTE: These tests rely on CreateNewBlock doing its own self-validation!

View file

@ -19,9 +19,6 @@ using namespace std;
map<uint256, CAlert> mapAlerts; map<uint256, CAlert> mapAlerts;
CCriticalSection cs_mapAlerts; CCriticalSection cs_mapAlerts;
static const char* pszMainKey = "04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284";
static const char* pszTestKey = "04302390343f91cc401d56d68b123028bf52e5fca1939df127f63c6467cdf9c8e2c14b61104cf817d0b780da337893ecc4aaff1309e536162dabbdb45200ca2b0a";
void CUnsignedAlert::SetNull() void CUnsignedAlert::SetNull()
{ {
nVersion = 1; nVersion = 1;
@ -144,7 +141,7 @@ bool CAlert::RelayTo(CNode* pnode) const
bool CAlert::CheckSignature() const bool CAlert::CheckSignature() const
{ {
CPubKey key(ParseHex(fTestNet ? pszTestKey : pszMainKey)); CPubKey key(Params().AlertKey());
if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig)) if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig))
return error("CAlert::CheckSignature() : verify signature failed"); return error("CAlert::CheckSignature() : verify signature failed");

View file

@ -18,6 +18,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "chainparams.h"
#include "bignum.h" #include "bignum.h"
#include "key.h" #include "key.h"
#include "script.h" #include "script.h"
@ -270,21 +271,13 @@ public:
class CBitcoinAddress : public CBase58Data class CBitcoinAddress : public CBase58Data
{ {
public: public:
enum
{
PUBKEY_ADDRESS = 0,
SCRIPT_ADDRESS = 5,
PUBKEY_ADDRESS_TEST = 111,
SCRIPT_ADDRESS_TEST = 196,
};
bool Set(const CKeyID &id) { bool Set(const CKeyID &id) {
SetData(fTestNet ? PUBKEY_ADDRESS_TEST : PUBKEY_ADDRESS, &id, 20); SetData(Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS), &id, 20);
return true; return true;
} }
bool Set(const CScriptID &id) { bool Set(const CScriptID &id) {
SetData(fTestNet ? SCRIPT_ADDRESS_TEST : SCRIPT_ADDRESS, &id, 20); SetData(Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS), &id, 20);
return true; return true;
} }
@ -295,32 +288,10 @@ public:
bool IsValid() const bool IsValid() const
{ {
unsigned int nExpectedSize = 20; bool fCorrectSize = vchData.size() == 20;
bool fExpectTestNet = false; bool fKnownVersion = nVersion == Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS) ||
switch(nVersion) nVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS);
{ return fCorrectSize && fKnownVersion;
case PUBKEY_ADDRESS:
nExpectedSize = 20; // Hash of public key
fExpectTestNet = false;
break;
case SCRIPT_ADDRESS:
nExpectedSize = 20; // Hash of CScript
fExpectTestNet = false;
break;
case PUBKEY_ADDRESS_TEST:
nExpectedSize = 20;
fExpectTestNet = true;
break;
case SCRIPT_ADDRESS_TEST:
nExpectedSize = 20;
fExpectTestNet = true;
break;
default:
return false;
}
return fExpectTestNet == fTestNet && vchData.size() == nExpectedSize;
} }
CBitcoinAddress() CBitcoinAddress()
@ -345,48 +316,27 @@ public:
CTxDestination Get() const { CTxDestination Get() const {
if (!IsValid()) if (!IsValid())
return CNoDestination(); return CNoDestination();
switch (nVersion) { uint160 id;
case PUBKEY_ADDRESS: memcpy(&id, &vchData[0], 20);
case PUBKEY_ADDRESS_TEST: { if (nVersion == Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS))
uint160 id;
memcpy(&id, &vchData[0], 20);
return CKeyID(id); return CKeyID(id);
} else if (nVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS))
case SCRIPT_ADDRESS:
case SCRIPT_ADDRESS_TEST: {
uint160 id;
memcpy(&id, &vchData[0], 20);
return CScriptID(id); return CScriptID(id);
} else
} return CNoDestination();
return CNoDestination();
} }
bool GetKeyID(CKeyID &keyID) const { bool GetKeyID(CKeyID &keyID) const {
if (!IsValid()) if (!IsValid() || nVersion != Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS))
return false; return false;
switch (nVersion) { uint160 id;
case PUBKEY_ADDRESS: memcpy(&id, &vchData[0], 20);
case PUBKEY_ADDRESS_TEST: { keyID = CKeyID(id);
uint160 id; return true;
memcpy(&id, &vchData[0], 20);
keyID = CKeyID(id);
return true;
}
default: return false;
}
} }
bool IsScript() const { bool IsScript() const {
if (!IsValid()) return IsValid() && nVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS);
return false;
switch (nVersion) {
case SCRIPT_ADDRESS:
case SCRIPT_ADDRESS_TEST: {
return true;
}
default: return false;
}
} }
}; };
@ -401,7 +351,7 @@ public:
void SetKey(const CKey& vchSecret) void SetKey(const CKey& vchSecret)
{ {
assert(vchSecret.IsValid()); assert(vchSecret.IsValid());
SetData(fTestNet ? 239 : 128, vchSecret.begin(), vchSecret.size()); SetData(Params().Base58Prefix(CChainParams::SECRET_KEY), vchSecret.begin(), vchSecret.size());
if (vchSecret.IsCompressed()) if (vchSecret.IsCompressed())
vchData.push_back(1); vchData.push_back(1);
} }
@ -415,20 +365,9 @@ public:
bool IsValid() const bool IsValid() const
{ {
bool fExpectTestNet = false; bool fExpectedFormat = vchData.size() == 32 || (vchData.size() == 33 && vchData[32] == 1);
switch(nVersion) bool fCorrectVersion = nVersion == Params().Base58Prefix(CChainParams::SECRET_KEY);
{ return fExpectedFormat && fCorrectVersion;
case 128:
break;
case 239:
fExpectTestNet = true;
break;
default:
return false;
}
return fExpectTestNet == fTestNet && (vchData.size() == 32 || (vchData.size() == 33 && vchData[32] == 1));
} }
bool SetString(const char* pszSecret) bool SetString(const char* pszSecret)

View file

@ -67,6 +67,10 @@ bool AppInit(int argc, char* argv[])
if (fCommandLine) if (fCommandLine)
{ {
if (!SelectParamsFromCommandLine()) {
fprintf(stderr, "Error: invalid combination of -regtest and -testnet.\n");
return false;
}
int ret = CommandLineRPC(argc, argv); int ret = CommandLineRPC(argc, argv);
exit(ret); exit(ret);
} }

View file

@ -3,6 +3,7 @@
// Distributed under the MIT/X11 software license, see the accompanying // Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "chainparams.h"
#include "init.h" #include "init.h"
#include "util.h" #include "util.h"
#include "sync.h" #include "sync.h"
@ -38,11 +39,6 @@ static map<string, boost::shared_ptr<deadline_timer> > deadlineTimers;
static ssl::context* rpc_ssl_context = NULL; static ssl::context* rpc_ssl_context = NULL;
static boost::thread_group* rpc_worker_group = NULL; static boost::thread_group* rpc_worker_group = NULL;
static inline unsigned short GetDefaultRPCPort()
{
return GetBoolArg("-testnet", false) ? 18332 : 8332;
}
Object JSONRPCError(int code, const string& message) Object JSONRPCError(int code, const string& message)
{ {
Object error; Object error;
@ -724,8 +720,8 @@ static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor<Protocol,
void StartRPCThreads() void StartRPCThreads()
{ {
strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"];
if ((mapArgs["-rpcpassword"] == "") || if (((mapArgs["-rpcpassword"] == "") ||
(mapArgs["-rpcuser"] == mapArgs["-rpcpassword"])) (mapArgs["-rpcuser"] == mapArgs["-rpcpassword"])) && Params().RequireRPCPassword())
{ {
unsigned char rand_pwd[32]; unsigned char rand_pwd[32];
RAND_bytes(rand_pwd, 32); RAND_bytes(rand_pwd, 32);
@ -780,7 +776,7 @@ void StartRPCThreads()
// Try a dual IPv6/IPv4 socket, falling back to separate IPv4 and IPv6 sockets // Try a dual IPv6/IPv4 socket, falling back to separate IPv4 and IPv6 sockets
const bool loopback = !mapArgs.count("-rpcallowip"); const bool loopback = !mapArgs.count("-rpcallowip");
asio::ip::address bindAddress = loopback ? asio::ip::address_v6::loopback() : asio::ip::address_v6::any(); asio::ip::address bindAddress = loopback ? asio::ip::address_v6::loopback() : asio::ip::address_v6::any();
ip::tcp::endpoint endpoint(bindAddress, GetArg("-rpcport", GetDefaultRPCPort())); ip::tcp::endpoint endpoint(bindAddress, GetArg("-rpcport", Params().RPCPort()));
boost::system::error_code v6_only_error; boost::system::error_code v6_only_error;
boost::shared_ptr<ip::tcp::acceptor> acceptor(new ip::tcp::acceptor(*rpc_io_service)); boost::shared_ptr<ip::tcp::acceptor> acceptor(new ip::tcp::acceptor(*rpc_io_service));
@ -1078,7 +1074,7 @@ Object CallRPC(const string& strMethod, const Array& params)
asio::ssl::stream<asio::ip::tcp::socket> sslStream(io_service, context); asio::ssl::stream<asio::ip::tcp::socket> sslStream(io_service, context);
SSLIOStreamDevice<asio::ip::tcp> d(sslStream, fUseSSL); SSLIOStreamDevice<asio::ip::tcp> d(sslStream, fUseSSL);
iostreams::stream< SSLIOStreamDevice<asio::ip::tcp> > stream(d); iostreams::stream< SSLIOStreamDevice<asio::ip::tcp> > stream(d);
if (!d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", itostr(GetDefaultRPCPort())))) if (!d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", itostr(Params().RPCPort()))))
throw runtime_error("couldn't connect to server"); throw runtime_error("couldn't connect to server");
// HTTP basic authentication // HTTP basic authentication

286
src/chainparams.cpp Normal file
View file

@ -0,0 +1,286 @@
// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 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 "assert.h"
#include "chainparams.h"
#include "main.h"
#include "util.h"
//
// Main network
//
unsigned int pnSeed[] =
{
0xe473042e, 0xb177f2ad, 0xd63f3fb2, 0xf864f736, 0x44a23ac7, 0xcf6d9650, 0xd648042e, 0x0536f447,
0x3c654ed0, 0x3e16a5bc, 0xa38e09b0, 0xdfae795b, 0xabfeca5b, 0x94ad7840, 0xf3b9f1c7, 0xbe70e0ad,
0x3bbd09b0, 0x8d0c7dd5, 0x3b2a7332, 0x1a06175e, 0x581f175e, 0xca0d2dcc, 0x0fdbc658, 0xcf591ec7,
0x295a12b2, 0xb4707bce, 0x68bb09b0, 0x4e735747, 0x89709553, 0x05a7814e, 0x5b8ec658, 0x402c5512,
0xe80d0905, 0x17681a5e, 0xc02aa748, 0x9f811741, 0x5f321cb0, 0x23e1ee47, 0xaf7f170c, 0xaa240ab0,
0xedea6257, 0x76106bc1, 0x2cf310cc, 0x08612acb, 0x9c682e4e, 0x8e963c6c, 0x443c795b, 0x22e246b8,
0xfa1f2dcc, 0x90118140, 0x3821042e, 0x33c3fd2e, 0x10046d5b, 0x40d14b3e, 0x7fb8f8ce, 0x67696550,
0xeeecbe58, 0x4f341745, 0x46b8fbd5, 0xc8463932, 0x6b73e862, 0x4c715932, 0x4a6785d5, 0xce3a64c2,
0xde9604c7, 0x9b06884f, 0x18002a45, 0xea9bc345, 0xc4f1c658, 0xe475c1c7, 0xdd3e795b, 0x9722175e,
0x34562f4e, 0x66c46e4e, 0x40bb1243, 0x7d9171d0, 0x17b8dbd5, 0x63cbfd2e, 0x1a08b8d8, 0x6175a73b,
0x228d2660, 0x8627c658, 0x9c566644, 0x38cca5bc, 0x3089de5b, 0x92e25f5d, 0xa393f73f, 0xcc92dc3e,
0x27487446, 0x62cbfd2e, 0x9d983b45, 0xf72a09b0, 0xf75f042e, 0x6434bb6a, 0xb29e77d8, 0x19be4fd9,
0x76443243, 0x9dd72645, 0x694cef43, 0x89c2efd5, 0x5f1c5058, 0x46c6e45b, 0xe1391b40, 0x77ccefd5,
0x472e5a6d, 0x85709553, 0xdd4f5d4c, 0x64ef5a46, 0x7f0ae502, 0xcf08d850, 0x3460042e, 0xeafa2d42,
0x793c9044, 0x9d094746, 0x1ab9b153, 0xbfe9a5bc, 0x34771fb0, 0xb7722e32, 0x1168964b, 0x19b06ab8,
0x19243b25, 0x13188045, 0xb4070905, 0x728ebb5d, 0x44f24ac8, 0xa317fead, 0x642f6a57, 0x3d951f32,
0x3d312e4e, 0xfac4d048, 0xefc4dd50, 0x52b9f1c7, 0xc14d3cc3, 0x0219ea44, 0x3b79d058, 0xfa217242,
0x39c80647, 0xfb697252, 0x1d495a42, 0x0aa81f4e, 0x58249ab8, 0xe6a8e6c3, 0x2bc4dad8, 0x85963c6c,
0xa4ce09b0, 0x2005f536, 0x5cc2703e, 0x1992de43, 0x74e86b4c, 0xe7085653, 0xf5e15a51, 0xb4872b60,
0x29e2b162, 0xa07ea053, 0x8229fd18, 0x4562ec4d, 0x8dec814e, 0x36cfa4cf, 0x96461032, 0x3c8770de,
0xd10a1f5f, 0x95934641, 0x97cd65d0, 0x2e35324a, 0x2566ba1f, 0x1ca1a9d1, 0xb808b8d5, 0xf9a24a5d,
0xafc8d431, 0xe4b8d9b2, 0x0f5321b2, 0x330bc658, 0x74b347ce, 0x972babd5, 0x044f7d4f, 0x06562f4e,
0x8b8d3c6c, 0x3507c658, 0xe4174e4d, 0xf1c009b0, 0x52249ab8, 0x27211772, 0xf6a9ba59, 0x7a391b40,
0x855dc6c0, 0x291f20b2, 0xe29bc345, 0x90963c6c, 0x0af70732, 0x4242a91f, 0x4c531d48, 0xa32df948,
0x627e3044, 0x65be1f54, 0x1a0cbf83, 0x6a443532, 0x8d5f1955, 0xbafa8132, 0x3534bdd5, 0xca019dd9,
0x8a0d9332, 0x5584e7d8, 0x7cd1f25e, 0xeabe3fb2, 0x2945d0d1, 0x46415718, 0x70d6042e, 0x99eb76d0,
0x9ece09b0, 0xb3777418, 0x5e5e91d9, 0x237a3ab0, 0xf512b62e, 0x45dec347, 0x59b7f862, 0x4c443b25,
0x3cc6484b, 0x9a8ec6d1, 0x021eea44, 0xc9483944, 0xfd567e32, 0xfd204bb2, 0xc5330bcc, 0x5202894e,
0xf9e309b0, 0x4cc17557, 0xdb9064ae, 0xe19e77d8, 0x25857f60, 0xeb4a15ad, 0x1f47f554, 0xea4472d9,
0xd20de593, 0xf5733b25, 0x11892b54, 0x5729d35f, 0xe6188cd1, 0x488b132e, 0x541c534a, 0xa8e854ae,
0xa255a66c, 0x33688763, 0xc6629ac6, 0xc20a6265, 0xcd92a059, 0x72029d3b, 0x4c298f5e, 0x51452e4e,
0xbb065058, 0x15fd2dcc, 0xf40c135e, 0x615a0bad, 0x0c6a6805, 0x4971a7ad, 0x17f2a5d5, 0xf8babf47,
0xb61f50ad, 0x4e1451b1, 0xf72d9252, 0x5c2abe58, 0xbd987c61, 0x084ae5cf, 0x20781fb0, 0x38b0f160,
0x18aac705, 0x14f86dc1, 0x5556f481, 0x0a36c144, 0xeb446e4c, 0x2c1c0d6c, 0xbd0ff860, 0x869f92db,
0x36c94f4c, 0x05502444, 0x148fe55b, 0xd5301e59, 0xd57a8f45, 0x110dc04a, 0x8670fc36, 0xee733b25,
0xca56f481, 0x2a5c3bae, 0x844b0905, 0x1e51fe53, 0x0241c244, 0x59c0614e, 0x94e70a55, 0x7312fead,
0xb735be44, 0xa55d0905, 0x2f63962e, 0x14a4e15b, 0x63f8f05c, 0x62d0d262, 0x3cab41ad, 0x87f1b1cb,
0x018da6b8, 0xb3967dd5, 0xcb56f481, 0x685ad718, 0x3b4aeeca, 0x8d106bc1, 0x51180905, 0x72660f48,
0x1521a243, 0x5b56f481, 0x6390e560, 0xdd61464e, 0x58353b25, 0x553fc062, 0x27c45d59, 0xacc62e4e,
0x0d5a1cd9, 0x7f65f442, 0xbdeef660, 0xf1bd1855, 0xf8473cae, 0x13b120b2, 0x442440d0, 0x53fd4352,
0xa305fc57, 0x458be84d, 0x639ce1c3, 0xebaaee47, 0x95e2c247, 0xf056f481, 0x6256f481, 0x1d87c65e,
0x0a453418, 0x5beb175e, 0xd64f1618, 0xc360795b, 0x2fbf5753, 0xa8c58e53, 0x651cec52, 0x9d37b043,
0x124a9758, 0x5242e4a9, 0x89913c6c, 0x880efe2e, 0x2f2f2f0c, 0x72b26751, 0x2896e46d, 0x80f4166c,
0x320d59ad, 0xc50151d0, 0x11a8aa43, 0xccf56057, 0x5fbad118, 0x4719b151, 0x2b5f4bc0, 0x4d7a4a50,
0xad06e047, 0x62ef5a46, 0x5aebde58, 0xdf7aa66c, 0x851acb50, 0x66b9a559, 0x3e9bb153, 0xcc512f2e,
0xc073b08e, 0xd519be58, 0xe981ea4d, 0x12fd50cb, 0x378739ad, 0x06683cae, 0xa22310b2, 0xc185c705,
0x8741b545, 0xa26c8318, 0x22d5bc43, 0x39201ec0, 0x68581e3e, 0xdc9bcf62, 0xd508cc82, 0xb149675b,
0x4c9609b0, 0x84feb84c, 0x08291e2e, 0xfd2253b2, 0x1fd269c1, 0xc9483932, 0x4d641fb0, 0x7d37c918,
0xa9de20ad, 0x77e2d655, 0x6d421b59, 0xd7668f80, 0xced09b62, 0xa9e5a5bc, 0xa4074e18, 0x60fc5ecc,
0x01300148, 0x68062444, 0xb4224847, 0xed3aa443, 0xb772fb43, 0x9f56f481, 0x220dfd18, 0x8e1c3d6c,
0xc44f09b0, 0x7df2bb73, 0xe22fb844, 0xea534242, 0xb6a755d4, 0xa036654b, 0x138ece5b, 0xda65d3c3,
0x955871bc, 0x792124b0, 0xfc82594c, 0x851d494b, 0x2c7aee47, 0x26af46b8, 0x1416252e, 0xa8abb944,
0x36c49d25, 0x674f645d, 0x363646b8, 0x9e1a2942, 0x66d0c154, 0xc6c2a545, 0x3570f2ad, 0xe7d547c7,
0x7d104932, 0x18cb9c18, 0x1dcfa4cf, 0xd156f481, 0x2a02b91f, 0x3eeb3fa8, 0xcac4175e, 0x34146d42,
0x994c4d46, 0x5666f440, 0x85d6713e, 0x5ecb296c, 0x0ea0ae46, 0x87e69f42, 0xc58409b0, 0x1f3436ae,
0x21dc6a57, 0x4ad1cd42, 0xfb8c1a4c, 0x52d3dab2, 0x3769894b, 0xb52f1c62, 0x3677916d, 0x82b3fe57,
0x493d4ac6, 0x9f963c6c, 0x5d91ff60, 0x458e0dad, 0xa49d0947, 0x491a3e18, 0x4aadcd5b, 0x0e46494b,
0x1d1610ad, 0x1a10af5d, 0x4956f481, 0x207a3eae, 0x77e73244, 0xfa3b8742, 0x3261fc36, 0xfcebf536,
0x1662e836, 0xf655f636, 0xa2dbd0ad, 0x23036693, 0x30448432, 0xa2b03463, 0x30730344, 0x8e4a6882,
0x0c50a1cb, 0xc8d8c06b, 0xc9cd6191, 0xf443db50, 0xa9553c50, 0x23145847, 0xc35da66c, 0x29c12a60,
0x55c2b447, 0x7434f75c, 0x61660640, 0xde2a7018, 0xc639494c, 0x1c306fce, 0x19b89244, 0xd29a6462,
0x462cd1b2, 0x29902f44, 0x2817fa53, 0x21a30905, 0x7777ae46, 0x288443a1, 0x7bee5148, 0xc2a8b043,
0xf5c3d35f, 0x2311ef84, 0x57de08a4, 0x6b221bb2, 0xf2625846, 0x4b9e09b0, 0xa24f880e, 0x22b11447,
0xb3a0c744, 0x919e77d8, 0xec8b64ae, 0xff5c8d45, 0x7b15b484, 0x32679a5f, 0xba80b62e, 0x05c25c61,
0x60014746, 0x5e8fb04c, 0xe67c0905, 0x4329c658, 0xac8fe555, 0xf875e647, 0x67406386, 0x35ceea18,
0xbb79484b, 0xd7b9fa62, 0x238209b0, 0x208a1d32, 0x9630995e, 0x039c1318, 0x6e48006c, 0x60582344,
0xadbb0150, 0x853fd462, 0x03772e4e, 0x652ce960, 0x49b630ad, 0x9993af43, 0x3735b34b, 0x548a07d9,
0x55a44aad, 0xa23d1bcc, 0xfdbb2f4e, 0x530b24a0, 0x0a44b451, 0x6827c657, 0x1f66494b, 0x4e680a47,
0x77e7b747, 0xa5eb3fa8, 0x6649764a, 0xd4e76c4b, 0x2c691fb0, 0xf1292e44, 0xc6d6c774, 0x85d23775,
0x28275f4d, 0x259ae46d, 0x02424e81, 0x5f16be58, 0xe707c658, 0x49eae5c7, 0xd5d147ad, 0x9a7abdc3,
0xe8ac7fc7, 0x84ec3aae, 0xc24942d0, 0x294aa318, 0x08ac3d18, 0x8894042e, 0xb24609b0, 0x9bcaab58,
0xc400f712, 0xd5c512b8, 0x2c02cc62, 0x25080fd8, 0xed74a847, 0x18a5ec5e, 0x9850ec6d, 0xf8909758,
0x7f56f481, 0x4496f23c, 0xae27784f, 0xcb7cd93e, 0x06e32860, 0x50b9a84f, 0x3660434a, 0x09161f5f,
0x900486bc, 0x08055459, 0xe7ec1017, 0x7e39494c, 0x4f443b25, 0x14751a8a, 0x717d03d4, 0xbd0e24d8,
0x054b6f56, 0x854c496c, 0xd92a454a, 0xc39bd054, 0x6093614b, 0x9dbad754, 0x5bf0604a, 0x99f22305
};
class CMainParams : public CChainParams {
public:
CMainParams() {
// 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
// a large 4-byte int at any alignment.
pchMessageStart[0] = 0xf9;
pchMessageStart[1] = 0xbe;
pchMessageStart[2] = 0xb4;
pchMessageStart[3] = 0xd9;
vAlertPubKey = ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284");
nDefaultPort = 8333;
nRPCPort = 8332;
bnProofOfWorkLimit = CBigNum(~uint256(0) >> 32);
nSubsidyHalvingInterval = 210000;
// Build the genesis block. Note that the output of the genesis coinbase cannot
// be spent as it did not originally exist in the database.
//
// CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1)
// CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0)
// CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73)
// CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B)
// vMerkleTree: 4a5e1e
const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";
CTransaction txNew;
txNew.vin.resize(1);
txNew.vout.resize(1);
txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
txNew.vout[0].nValue = 50 * COIN;
txNew.vout[0].scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG;
genesis.vtx.push_back(txNew);
genesis.hashPrevBlock = 0;
genesis.hashMerkleRoot = genesis.BuildMerkleTree();
genesis.nVersion = 1;
genesis.nTime = 1231006505;
genesis.nBits = 0x1d00ffff;
genesis.nNonce = 2083236893;
hashGenesisBlock = genesis.GetHash();
assert(hashGenesisBlock == uint256("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"));
assert(genesis.hashMerkleRoot == uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
vSeeds.push_back(CDNSSeedData("bitcoin.sipa.be", "seed.bitcoin.sipa.be"));
vSeeds.push_back(CDNSSeedData("bluematt.me", "dnsseed.bluematt.me"));
vSeeds.push_back(CDNSSeedData("dashjr.org", "dnsseed.bitcoin.dashjr.org"));
vSeeds.push_back(CDNSSeedData("xf2.org", "bitseed.xf2.org"));
base58Prefixes[PUBKEY_ADDRESS] = 0;
base58Prefixes[SCRIPT_ADDRESS] = 5;
base58Prefixes[SECRET_KEY] = 128;
// Convert the pnSeeds array into usable address objects.
for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++)
{
// It'll only connect to one or two seed nodes because once it connects,
// it'll get a pile of addresses with newer timestamps.
// Seed nodes are given a random 'last seen time' of between one and two
// weeks ago.
const int64 nOneWeek = 7*24*60*60;
struct in_addr ip;
memcpy(&ip, &pnSeed[i], sizeof(ip));
CAddress addr(CService(ip, GetDefaultPort()));
addr.nTime = GetTime() - GetRand(nOneWeek) - nOneWeek;
vFixedSeeds.push_back(addr);
}
}
virtual const CBlock& GenesisBlock() const { return genesis; }
virtual Network NetworkID() const { return CChainParams::MAIN; }
virtual const vector<CAddress>& FixedSeeds() const {
return vFixedSeeds;
}
protected:
CBlock genesis;
vector<CAddress> vFixedSeeds;
};
static CMainParams mainParams;
//
// Testnet (v3)
//
class CTestNetParams : public CMainParams {
public:
CTestNetParams() {
// 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
// a large 4-byte int at any alignment.
pchMessageStart[0] = 0x0b;
pchMessageStart[1] = 0x11;
pchMessageStart[2] = 0x09;
pchMessageStart[3] = 0x07;
vAlertPubKey = ParseHex("04302390343f91cc401d56d68b123028bf52e5fca1939df127f63c6467cdf9c8e2c14b61104cf817d0b780da337893ecc4aaff1309e536162dabbdb45200ca2b0a");
nDefaultPort = 18333;
nRPCPort = 18332;
strDataDir = "testnet3";
// Modify the testnet genesis block so the timestamp is valid for a later start.
genesis.nTime = 1296688602;
genesis.nNonce = 414098458;
hashGenesisBlock = genesis.GetHash();
assert(hashGenesisBlock == uint256("000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"));
vFixedSeeds.clear();
vSeeds.clear();
vSeeds.push_back(CDNSSeedData("bitcoin.petertodd.org", "testnet-seed.bitcoin.petertodd.org"));
vSeeds.push_back(CDNSSeedData("bluematt.me", "testnet-seed.bluematt.me"));
base58Prefixes[PUBKEY_ADDRESS] = 111;
base58Prefixes[SCRIPT_ADDRESS] = 196;
base58Prefixes[SECRET_KEY] = 239;
}
virtual Network NetworkID() const { return CChainParams::TESTNET; }
};
static CTestNetParams testNetParams;
//
// Regression test
//
class CRegTestParams : public CTestNetParams {
public:
CRegTestParams() {
pchMessageStart[0] = 0xfa;
pchMessageStart[1] = 0xbf;
pchMessageStart[2] = 0xb5;
pchMessageStart[3] = 0xda;
nSubsidyHalvingInterval = 150;
bnProofOfWorkLimit = CBigNum(~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.
base58Prefixes[PUBKEY_ADDRESS] = 0;
base58Prefixes[SCRIPT_ADDRESS] = 5;
base58Prefixes[SECRET_KEY] = 128;
}
virtual bool RequireRPCPassword() const { return false; }
virtual Network NetworkID() const { return CChainParams::REGTEST; }
};
static CRegTestParams regTestParams;
static CChainParams *pCurrentParams = &mainParams;
const CChainParams &Params() {
return *pCurrentParams;
}
void SelectParams(CChainParams::Network network) {
switch (network) {
case CChainParams::MAIN:
pCurrentParams = &mainParams;
break;
case CChainParams::TESTNET:
pCurrentParams = &testNetParams;
break;
case CChainParams::REGTEST:
pCurrentParams = &regTestParams;
break;
default:
assert(false && "Unimplemented network");
return;
}
}
bool SelectParamsFromCommandLine() {
bool fRegTest = GetBoolArg("-regtest", false);
bool fTestNet = GetBoolArg("-testnet", false);
if (fTestNet && fRegTest) {
return false;
}
if (fRegTest) {
SelectParams(CChainParams::REGTEST);
} else if (fTestNet) {
SelectParams(CChainParams::TESTNET);
} else {
SelectParams(CChainParams::MAIN);
}
return true;
}

102
src/chainparams.h Normal file
View file

@ -0,0 +1,102 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2013 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_H
#define BITCOIN_CHAIN_PARAMS_H
#include "bignum.h"
#include "uint256.h"
#include "util.h"
#include <vector>
using namespace std;
#define MESSAGE_START_SIZE 4
typedef unsigned char MessageStartChars[MESSAGE_START_SIZE];
class CAddress;
class CBlock;
struct CDNSSeedData {
string name, host;
CDNSSeedData(const string &strName, const string &strHost) : name(strName), host(strHost) {}
};
/**
* CChainParams defines various tweakable parameters of a given instance of the
* Bitcoin system. There are three: the main network on which people trade goods
* and services, the public test network which gets reset from time to time and
* a regression test mode which is intended for private networks only. It has
* minimal difficulty to ensure that blocks can be found instantly.
*/
class CChainParams
{
public:
enum Network {
MAIN,
TESTNET,
REGTEST,
};
enum Base58Type {
PUBKEY_ADDRESS,
SCRIPT_ADDRESS,
SECRET_KEY,
MAX_BASE58_TYPES
};
const uint256& HashGenesisBlock() const { return hashGenesisBlock; }
const MessageStartChars& MessageStart() const { return pchMessageStart; }
const vector<unsigned char>& AlertKey() const { return vAlertPubKey; }
int GetDefaultPort() const { return nDefaultPort; }
const CBigNum& ProofOfWorkLimit() const { return bnProofOfWorkLimit; }
int SubsidyHalvingInterval() const { return nSubsidyHalvingInterval; }
virtual const CBlock& GenesisBlock() const = 0;
virtual bool RequireRPCPassword() const { return true; }
const string& DataDir() const { return strDataDir; }
virtual Network NetworkID() const = 0;
const vector<CDNSSeedData>& DNSSeeds() const { return vSeeds; }
int Base58Prefix(Base58Type type) const { return base58Prefixes[type]; }
virtual const vector<CAddress>& FixedSeeds() const = 0;
int RPCPort() const { return nRPCPort; }
protected:
CChainParams() {};
uint256 hashGenesisBlock;
MessageStartChars pchMessageStart;
// Raw pub key bytes for the broadcast alert signing key.
vector<unsigned char> vAlertPubKey;
int nDefaultPort;
int nRPCPort;
CBigNum bnProofOfWorkLimit;
int nSubsidyHalvingInterval;
string strDataDir;
vector<CDNSSeedData> vSeeds;
int base58Prefixes[MAX_BASE58_TYPES];
};
/**
* Return the currently selected parameters. This won't change after app startup
* outside of the unit tests.
*/
const CChainParams &Params();
/** Sets the params returned by Params() to those for the given network. */
void SelectParams(CChainParams::Network network);
/**
* Looks for -regtest or -testnet and then calls SelectParams as appropriate.
* Returns false if an invalid combination is given.
*/
bool SelectParamsFromCommandLine();
inline bool TestNet() {
// Note: it's deliberate that this returns "false" for regression test mode.
return Params().NetworkID() == CChainParams::TESTNET;
}
#endif

View file

@ -56,7 +56,7 @@ namespace Checkpoints
60000.0 // * estimated number of transactions per day after checkpoint 60000.0 // * estimated number of transactions per day after checkpoint
}; };
static MapCheckpoints mapCheckpointsTestnet = static MapCheckpoints mapCheckpointsTestnet =
boost::assign::map_list_of boost::assign::map_list_of
( 546, uint256("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")) ( 546, uint256("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70"))
; ;
@ -68,7 +68,7 @@ namespace Checkpoints
}; };
const CCheckpointData &Checkpoints() { const CCheckpointData &Checkpoints() {
if (fTestNet) if (TestNet())
return dataTestnet; return dataTestnet;
else else
return data; return data;

View file

@ -3,6 +3,7 @@
// Distributed under the MIT/X11 software license, see the accompanying // Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "chainparams.h"
#include "db.h" #include "db.h"
#include "util.h" #include "util.h"
#include "hash.h" #include "hash.h"
@ -488,8 +489,6 @@ void CDBEnv::Flush(bool fShutdown)
// CAddrDB // CAddrDB
// //
unsigned char CAddrDB::pchMessageStart[4] = { 0x00, 0x00, 0x00, 0x00 };
CAddrDB::CAddrDB() CAddrDB::CAddrDB()
{ {
pathAddr = GetDataDir() / "peers.dat"; pathAddr = GetDataDir() / "peers.dat";
@ -504,7 +503,7 @@ bool CAddrDB::Write(const CAddrMan& addr)
// serialize addresses, checksum data up to that point, then append csum // serialize addresses, checksum data up to that point, then append csum
CDataStream ssPeers(SER_DISK, CLIENT_VERSION); CDataStream ssPeers(SER_DISK, CLIENT_VERSION);
ssPeers << FLATDATA(CAddrDB::pchMessageStart); ssPeers << FLATDATA(Params().MessageStart());
ssPeers << addr; ssPeers << addr;
uint256 hash = Hash(ssPeers.begin(), ssPeers.end()); uint256 hash = Hash(ssPeers.begin(), ssPeers.end());
ssPeers << hash; ssPeers << hash;
@ -569,11 +568,11 @@ bool CAddrDB::Read(CAddrMan& addr)
unsigned char pchMsgTmp[4]; unsigned char pchMsgTmp[4];
try { try {
// de-serialize file header (CAddrDB::pchMessageStart magic number) and // de-serialize file header (network specific magic number) and ..
ssPeers >> FLATDATA(pchMsgTmp); ssPeers >> FLATDATA(pchMsgTmp);
// verify the network matches ours // ... verify the network matches ours
if (memcmp(pchMsgTmp, CAddrDB::pchMessageStart, sizeof(pchMsgTmp))) if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
return error("CAddrman::Read() : invalid network magic number"); return error("CAddrman::Read() : invalid network magic number");
// de-serialize address data into one CAddrMan object // de-serialize address data into one CAddrMan object

View file

@ -318,14 +318,10 @@ class CAddrDB
{ {
private: private:
boost::filesystem::path pathAddr; boost::filesystem::path pathAddr;
static unsigned char pchMessageStart[4];
public: public:
CAddrDB(); CAddrDB();
bool Write(const CAddrMan& addr); bool Write(const CAddrMan& addr);
bool Read(CAddrMan& addr); bool Read(CAddrMan& addr);
static void SetMessageStart(unsigned char _pchMessageStart[]) { memcpy(CAddrDB::pchMessageStart, _pchMessageStart, sizeof(CAddrDB::pchMessageStart)); }
}; };
#endif // BITCOIN_DB_H #endif // BITCOIN_DB_H

View file

@ -6,6 +6,7 @@
#include "init.h" #include "init.h"
#include "main.h" #include "main.h"
#include "core.h" #include "core.h"
#include "chainparams.h"
#include "txdb.h" #include "txdb.h"
#include "walletdb.h" #include "walletdb.h"
#include "bitcoinrpc.h" #include "bitcoinrpc.h"
@ -13,6 +14,7 @@
#include "util.h" #include "util.h"
#include "ui_interface.h" #include "ui_interface.h"
#include "checkpoints.h" #include "checkpoints.h"
#include "chainparams.h"
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp> #include <boost/filesystem/fstream.hpp>
@ -210,6 +212,8 @@ std::string HelpMessage()
strUsage += " -logtimestamps " + _("Prepend debug output with timestamp") + "\n"; strUsage += " -logtimestamps " + _("Prepend debug output with timestamp") + "\n";
strUsage += " -shrinkdebugfile " + _("Shrink debug.log file on client startup (default: 1 when no -debug)") + "\n"; strUsage += " -shrinkdebugfile " + _("Shrink debug.log file on client startup (default: 1 when no -debug)") + "\n";
strUsage += " -printtoconsole " + _("Send trace/debug info to console instead of debug.log file") + "\n"; strUsage += " -printtoconsole " + _("Send trace/debug info to console instead of debug.log file") + "\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";
#ifdef WIN32 #ifdef WIN32
strUsage += " -printtodebugger " + _("Send trace/debug info to debugger") + "\n"; strUsage += " -printtodebugger " + _("Send trace/debug info to debugger") + "\n";
#endif #endif
@ -366,8 +370,10 @@ bool AppInit2(boost::thread_group& threadGroup)
// ********************************************************* Step 2: parameter interactions // ********************************************************* Step 2: parameter interactions
fTestNet = GetBoolArg("-testnet", false);
Checkpoints::fEnabled = GetBoolArg("-checkpoints", true); Checkpoints::fEnabled = GetBoolArg("-checkpoints", true);
if (!SelectParamsFromCommandLine()) {
return InitError("Invalid combination of -testnet and -regtest.");
}
if (mapArgs.count("-bind")) { if (mapArgs.count("-bind")) {
// when specifying an explicit binding address, you want to listen on it // when specifying an explicit binding address, you want to listen on it
@ -572,7 +578,7 @@ bool AppInit2(boost::thread_group& threadGroup)
// ********************************************************* Step 6: network initialization // ********************************************************* Step 6: network initialization
RegisterNodeSignals(GetNodeSignals()); RegisterNodeSignals(GetNodeSignals());
int nSocksVersion = GetArg("-socks", 5); int nSocksVersion = GetArg("-socks", 5);
if (nSocksVersion != 4 && nSocksVersion != 5) if (nSocksVersion != 4 && nSocksVersion != 5)
return InitError(strprintf(_("Unknown -socks proxy version requested: %i"), nSocksVersion)); return InitError(strprintf(_("Unknown -socks proxy version requested: %i"), nSocksVersion));
@ -937,7 +943,6 @@ bool AppInit2(boost::thread_group& threadGroup)
nStart = GetTimeMillis(); nStart = GetTimeMillis();
{ {
CAddrDB::SetMessageStart(pchMessageStart);
CAddrDB adb; CAddrDB adb;
if (!adb.Read(addrman)) if (!adb.Read(addrman))
printf("Invalid or missing peers.dat; recreating\n"); printf("Invalid or missing peers.dat; recreating\n");

View file

@ -11,6 +11,7 @@
#include "init.h" #include "init.h"
#include "ui_interface.h" #include "ui_interface.h"
#include "checkqueue.h" #include "checkqueue.h"
#include "chainparams.h"
#include <boost/algorithm/string/replace.hpp> #include <boost/algorithm/string/replace.hpp>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp> #include <boost/filesystem/fstream.hpp>
@ -32,8 +33,6 @@ unsigned int nTransactionsUpdated = 0;
map<uint256, CBlockIndex*> mapBlockIndex; map<uint256, CBlockIndex*> mapBlockIndex;
std::vector<CBlockIndex*> vBlockIndexByHeight; std::vector<CBlockIndex*> vBlockIndexByHeight;
uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f");
static CBigNum bnProofOfWorkLimit(~uint256(0) >> 32);
CBlockIndex* pindexGenesisBlock = NULL; CBlockIndex* pindexGenesisBlock = NULL;
int nBestHeight = -1; int nBestHeight = -1;
uint256 nBestChainWork = 0; uint256 nBestChainWork = 0;
@ -201,7 +200,7 @@ void CBlockLocator::Set(const CBlockIndex* pindex)
if (vHave.size() > 10) if (vHave.size() > 10)
nStep *= 2; nStep *= 2;
} }
vHave.push_back(hashGenesisBlock); vHave.push_back(Params().HashGenesisBlock());
} }
int CBlockLocator::GetDistanceBack() int CBlockLocator::GetDistanceBack()
@ -254,7 +253,7 @@ uint256 CBlockLocator::GetBlockHash()
return hash; return hash;
} }
} }
return hashGenesisBlock; return Params().HashGenesisBlock();
} }
int CBlockLocator::GetHeight() int CBlockLocator::GetHeight()
@ -798,7 +797,7 @@ bool CTxMemPool::accept(CValidationState &state, CTransaction &tx, bool fLimitFr
return error("CTxMemPool::accept() : not accepting nLockTime beyond 2038 yet"); return error("CTxMemPool::accept() : not accepting nLockTime beyond 2038 yet");
// Rather not work on nonstandard transactions (unless -testnet) // Rather not work on nonstandard transactions (unless -testnet)
if (!fTestNet && !IsStandardTx(tx)) if (!TestNet() && !IsStandardTx(tx))
return error("CTxMemPool::accept() : nonstandard transaction type"); return error("CTxMemPool::accept() : nonstandard transaction type");
// is it already in the memory pool? // is it already in the memory pool?
@ -873,7 +872,7 @@ bool CTxMemPool::accept(CValidationState &state, CTransaction &tx, bool fLimitFr
} }
// Check for non-standard pay-to-script-hash in inputs // Check for non-standard pay-to-script-hash in inputs
if (!AreInputsStandard(tx, view) && !fTestNet) if (!TestNet() && !AreInputsStandard(tx, view))
return error("CTxMemPool::accept() : nonstandard transaction input"); return error("CTxMemPool::accept() : nonstandard transaction input");
// Note: if you modify this code to accept non-standard transactions, then // Note: if you modify this code to accept non-standard transactions, then
@ -1183,8 +1182,8 @@ int64 static GetBlockValue(int nHeight, int64 nFees)
{ {
int64 nSubsidy = 50 * COIN; int64 nSubsidy = 50 * COIN;
// Subsidy is cut in half every 210000 blocks, which will occur approximately every 4 years // Subsidy is cut in half every 210,000 blocks which will occur approximately every 4 years.
nSubsidy >>= (nHeight / 210000); nSubsidy >>= (nHeight / Params().SubsidyHalvingInterval());
return nSubsidy + nFees; return nSubsidy + nFees;
} }
@ -1199,28 +1198,29 @@ static const int64 nInterval = nTargetTimespan / nTargetSpacing;
// //
unsigned int ComputeMinWork(unsigned int nBase, int64 nTime) unsigned int ComputeMinWork(unsigned int nBase, int64 nTime)
{ {
const CBigNum &bnLimit = Params().ProofOfWorkLimit();
// Testnet has min-difficulty blocks // Testnet has min-difficulty blocks
// after nTargetSpacing*2 time between blocks: // after nTargetSpacing*2 time between blocks:
if (fTestNet && nTime > nTargetSpacing*2) if (TestNet() && nTime > nTargetSpacing*2)
return bnProofOfWorkLimit.GetCompact(); return bnLimit.GetCompact();
CBigNum bnResult; CBigNum bnResult;
bnResult.SetCompact(nBase); bnResult.SetCompact(nBase);
while (nTime > 0 && bnResult < bnProofOfWorkLimit) while (nTime > 0 && bnResult < bnLimit)
{ {
// Maximum 400% adjustment... // Maximum 400% adjustment...
bnResult *= 4; bnResult *= 4;
// ... in best-case exactly 4-times-normal target time // ... in best-case exactly 4-times-normal target time
nTime -= nTargetTimespan*4; nTime -= nTargetTimespan*4;
} }
if (bnResult > bnProofOfWorkLimit) if (bnResult > bnLimit)
bnResult = bnProofOfWorkLimit; bnResult = bnLimit;
return bnResult.GetCompact(); return bnResult.GetCompact();
} }
unsigned int static GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock) unsigned int static GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock)
{ {
unsigned int nProofOfWorkLimit = bnProofOfWorkLimit.GetCompact(); unsigned int nProofOfWorkLimit = Params().ProofOfWorkLimit().GetCompact();
// Genesis block // Genesis block
if (pindexLast == NULL) if (pindexLast == NULL)
@ -1229,9 +1229,9 @@ unsigned int static GetNextWorkRequired(const CBlockIndex* pindexLast, const CBl
// Only change once per interval // Only change once per interval
if ((pindexLast->nHeight+1) % nInterval != 0) if ((pindexLast->nHeight+1) % nInterval != 0)
{ {
// Special difficulty rule for testnet: if (TestNet())
if (fTestNet)
{ {
// Special difficulty rule for testnet:
// If the new block's timestamp is more than 2* 10 minutes // If the new block's timestamp is more than 2* 10 minutes
// then allow mining of a min-difficulty block. // then allow mining of a min-difficulty block.
if (pblock->nTime > pindexLast->nTime + nTargetSpacing*2) if (pblock->nTime > pindexLast->nTime + nTargetSpacing*2)
@ -1245,7 +1245,6 @@ unsigned int static GetNextWorkRequired(const CBlockIndex* pindexLast, const CBl
return pindex->nBits; return pindex->nBits;
} }
} }
return pindexLast->nBits; return pindexLast->nBits;
} }
@ -1269,8 +1268,8 @@ unsigned int static GetNextWorkRequired(const CBlockIndex* pindexLast, const CBl
bnNew *= nActualTimespan; bnNew *= nActualTimespan;
bnNew /= nTargetTimespan; bnNew /= nTargetTimespan;
if (bnNew > bnProofOfWorkLimit) if (bnNew > Params().ProofOfWorkLimit())
bnNew = bnProofOfWorkLimit; bnNew = Params().ProofOfWorkLimit();
/// debug print /// debug print
printf("GetNextWorkRequired RETARGET\n"); printf("GetNextWorkRequired RETARGET\n");
@ -1287,7 +1286,7 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits)
bnTarget.SetCompact(nBits); bnTarget.SetCompact(nBits);
// Check range // Check range
if (bnTarget <= 0 || bnTarget > bnProofOfWorkLimit) if (bnTarget <= 0 || bnTarget > Params().ProofOfWorkLimit())
return error("CheckProofOfWork() : nBits below minimum work"); return error("CheckProofOfWork() : nBits below minimum work");
// Check proof of work matches claimed amount // Check proof of work matches claimed amount
@ -1405,7 +1404,7 @@ void UpdateTime(CBlockHeader& block, const CBlockIndex* pindexPrev)
block.nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); block.nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
// Updating time can change work required on testnet: // Updating time can change work required on testnet:
if (fTestNet) if (TestNet())
block.nBits = GetNextWorkRequired(pindexPrev, &block); block.nBits = GetNextWorkRequired(pindexPrev, &block);
} }
@ -1694,7 +1693,7 @@ bool CBlock::ConnectBlock(CValidationState &state, CBlockIndex* pindex, CCoinsVi
// Special case for the genesis block, skipping connection of its transactions // Special case for the genesis block, skipping connection of its transactions
// (its coinbase is unspendable) // (its coinbase is unspendable)
if (GetHash() == hashGenesisBlock) { if (GetHash() == Params().HashGenesisBlock()) {
view.SetBestBlock(pindex); view.SetBestBlock(pindex);
pindexGenesisBlock = pindex; pindexGenesisBlock = pindex;
return true; return true;
@ -2222,7 +2221,7 @@ bool CBlock::AcceptBlock(CValidationState &state, CDiskBlockPos *dbp)
// Get prev block index // Get prev block index
CBlockIndex* pindexPrev = NULL; CBlockIndex* pindexPrev = NULL;
int nHeight = 0; int nHeight = 0;
if (hash != hashGenesisBlock) { if (hash != Params().HashGenesisBlock()) {
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashPrevBlock); map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashPrevBlock);
if (mi == mapBlockIndex.end()) if (mi == mapBlockIndex.end())
return state.DoS(10, error("AcceptBlock() : prev block not found")); return state.DoS(10, error("AcceptBlock() : prev block not found"));
@ -2249,8 +2248,8 @@ bool CBlock::AcceptBlock(CValidationState &state, CDiskBlockPos *dbp)
// Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded: // Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded:
if (nVersion < 2) if (nVersion < 2)
{ {
if ((!fTestNet && CBlockIndex::IsSuperMajority(2, pindexPrev, 950, 1000)) || if ((!TestNet() && CBlockIndex::IsSuperMajority(2, pindexPrev, 950, 1000)) ||
(fTestNet && CBlockIndex::IsSuperMajority(2, pindexPrev, 75, 100))) (TestNet() && CBlockIndex::IsSuperMajority(2, pindexPrev, 75, 100)))
{ {
return state.Invalid(error("AcceptBlock() : rejected nVersion=1 block")); return state.Invalid(error("AcceptBlock() : rejected nVersion=1 block"));
} }
@ -2259,8 +2258,8 @@ bool CBlock::AcceptBlock(CValidationState &state, CDiskBlockPos *dbp)
if (nVersion >= 2) if (nVersion >= 2)
{ {
// if 750 of the last 1,000 blocks are version 2 or greater (51/100 if testnet): // if 750 of the last 1,000 blocks are version 2 or greater (51/100 if testnet):
if ((!fTestNet && CBlockIndex::IsSuperMajority(2, pindexPrev, 750, 1000)) || if ((!TestNet() && CBlockIndex::IsSuperMajority(2, pindexPrev, 750, 1000)) ||
(fTestNet && CBlockIndex::IsSuperMajority(2, pindexPrev, 51, 100))) (TestNet() && CBlockIndex::IsSuperMajority(2, pindexPrev, 51, 100)))
{ {
CScript expect = CScript() << nHeight; CScript expect = CScript() << nHeight;
if (!std::equal(expect.begin(), expect.end(), vtx[0].vin[0].scriptSig.begin())) if (!std::equal(expect.begin(), expect.end(), vtx[0].vin[0].scriptSig.begin()))
@ -2790,21 +2789,9 @@ void UnloadBlockIndex()
bool LoadBlockIndex() bool LoadBlockIndex()
{ {
if (fTestNet)
{
pchMessageStart[0] = 0x0b;
pchMessageStart[1] = 0x11;
pchMessageStart[2] = 0x09;
pchMessageStart[3] = 0x07;
hashGenesisBlock = uint256("000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943");
}
//
// Load block index from databases // Load block index from databases
//
if (!fReindex && !LoadBlockIndexDB()) if (!fReindex && !LoadBlockIndexDB())
return false; return false;
return true; return true;
} }
@ -2821,47 +2808,9 @@ bool InitBlockIndex() {
// Only add the genesis block if not reindexing (in which case we reuse the one already on disk) // Only add the genesis block if not reindexing (in which case we reuse the one already on disk)
if (!fReindex) { if (!fReindex) {
// Genesis Block:
// CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1)
// CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0)
// CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73)
// CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B)
// vMerkleTree: 4a5e1e
// Genesis block
const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";
CTransaction txNew;
txNew.vin.resize(1);
txNew.vout.resize(1);
txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
txNew.vout[0].nValue = 50 * COIN;
txNew.vout[0].scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG;
CBlock block;
block.vtx.push_back(txNew);
block.hashPrevBlock = 0;
block.hashMerkleRoot = block.BuildMerkleTree();
block.nVersion = 1;
block.nTime = 1231006505;
block.nBits = 0x1d00ffff;
block.nNonce = 2083236893;
if (fTestNet)
{
block.nTime = 1296688602;
block.nNonce = 414098458;
}
//// debug print
uint256 hash = block.GetHash();
printf("%s\n", hash.ToString().c_str());
printf("%s\n", hashGenesisBlock.ToString().c_str());
printf("%s\n", block.hashMerkleRoot.ToString().c_str());
assert(block.hashMerkleRoot == uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
block.print();
assert(hash == hashGenesisBlock);
// Start new block file
try { try {
CBlock &block = const_cast<CBlock&>(Params().GenesisBlock());
// Start new block file
unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION); unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
CDiskBlockPos blockPos; CDiskBlockPos blockPos;
CValidationState state; CValidationState state;
@ -2978,10 +2927,10 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
try { try {
// locate a header // locate a header
unsigned char buf[4]; unsigned char buf[4];
blkdat.FindByte(pchMessageStart[0]); blkdat.FindByte(Params().MessageStart()[0]);
nRewind = blkdat.GetPos()+1; nRewind = blkdat.GetPos()+1;
blkdat >> FLATDATA(buf); blkdat >> FLATDATA(buf);
if (memcmp(buf, pchMessageStart, 4)) if (memcmp(buf, Params().MessageStart(), 4))
continue; continue;
// read size // read size
blkdat >> nSize; blkdat >> nSize;
@ -3126,12 +3075,6 @@ bool static AlreadyHave(const CInv& inv)
// 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
// a large 4-byte int at any alignment.
unsigned char pchMessageStart[4] = { 0xf9, 0xbe, 0xb4, 0xd9 };
void static ProcessGetData(CNode* pfrom) void static ProcessGetData(CNode* pfrom)
{ {
std::deque<CInv>::iterator it = pfrom->vRecvGetData.begin(); std::deque<CInv>::iterator it = pfrom->vRecvGetData.begin();
@ -3854,7 +3797,7 @@ bool ProcessMessages(CNode* pfrom)
it++; it++;
// Scan for message start // Scan for message start
if (memcmp(msg.hdr.pchMessageStart, pchMessageStart, sizeof(pchMessageStart)) != 0) { if (memcmp(msg.hdr.pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0) {
printf("\n\nPROCESSMESSAGE: INVALID MESSAGESTART\n\n"); printf("\n\nPROCESSMESSAGE: INVALID MESSAGESTART\n\n");
fOk = false; fOk = false;
break; break;
@ -4598,8 +4541,12 @@ void static BitcoinMiner(CWallet *pwallet)
unsigned int nExtraNonce = 0; unsigned int nExtraNonce = 0;
try { loop { try { loop {
while (vNodes.empty()) if (Params().NetworkID() != CChainParams::REGTEST) {
MilliSleep(1000); // 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 // Create new block
@ -4661,6 +4608,12 @@ void static BitcoinMiner(CWallet *pwallet)
SetThreadPriority(THREAD_PRIORITY_NORMAL); SetThreadPriority(THREAD_PRIORITY_NORMAL);
CheckWork(pblock, *pwalletMain, reservekey); CheckWork(pblock, *pwalletMain, reservekey);
SetThreadPriority(THREAD_PRIORITY_LOWEST); SetThreadPriority(THREAD_PRIORITY_LOWEST);
// In regression test mode, stop mining after a block is found. This
// allows developers to controllably generate a block on demand.
if (Params().NetworkID() == CChainParams::REGTEST)
throw boost::thread_interrupted();
break; break;
} }
} }
@ -4696,7 +4649,7 @@ void static BitcoinMiner(CWallet *pwallet)
// Check for stop or if block needs to be rebuilt // Check for stop or if block needs to be rebuilt
boost::this_thread::interruption_point(); boost::this_thread::interruption_point();
if (vNodes.empty()) if (vNodes.empty() && Params().NetworkID() != CChainParams::REGTEST)
break; break;
if (nBlockNonce >= 0xffff0000) if (nBlockNonce >= 0xffff0000)
break; break;
@ -4708,7 +4661,7 @@ void static BitcoinMiner(CWallet *pwallet)
// Update nTime every few seconds // Update nTime every few seconds
UpdateTime(*pblock, pindexPrev); UpdateTime(*pblock, pindexPrev);
nBlockTime = ByteReverse(pblock->nTime); nBlockTime = ByteReverse(pblock->nTime);
if (fTestNet) if (TestNet())
{ {
// Changing pblock->nTime can change work required on testnet: // Changing pblock->nTime can change work required on testnet:
nBlockBits = ByteReverse(pblock->nBits); nBlockBits = ByteReverse(pblock->nBits);
@ -4728,8 +4681,12 @@ void GenerateBitcoins(bool fGenerate, CWallet* pwallet)
static boost::thread_group* minerThreads = NULL; static boost::thread_group* minerThreads = NULL;
int nThreads = GetArg("-genproclimit", -1); int nThreads = GetArg("-genproclimit", -1);
if (nThreads < 0) if (nThreads < 0) {
nThreads = boost::thread::hardware_concurrency(); if (Params().NetworkID() == CChainParams::REGTEST)
nThreads = 1;
else
nThreads = boost::thread::hardware_concurrency();
}
if (minerThreads != NULL) if (minerThreads != NULL)
{ {

View file

@ -70,7 +70,6 @@ extern CCriticalSection cs_main;
extern std::map<uint256, CBlockIndex*> mapBlockIndex; extern std::map<uint256, CBlockIndex*> mapBlockIndex;
extern std::vector<CBlockIndex*> vBlockIndexByHeight; extern std::vector<CBlockIndex*> vBlockIndexByHeight;
extern std::set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexValid; extern std::set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexValid;
extern uint256 hashGenesisBlock;
extern CBlockIndex* pindexGenesisBlock; extern CBlockIndex* pindexGenesisBlock;
extern int nBestHeight; extern int nBestHeight;
extern uint256 nBestChainWork; extern uint256 nBestChainWork;
@ -86,7 +85,6 @@ extern int64 nHPSTimerStart;
extern int64 nTimeBestReceived; extern int64 nTimeBestReceived;
extern CCriticalSection cs_setpwalletRegistered; extern CCriticalSection cs_setpwalletRegistered;
extern std::set<CWallet*> setpwalletRegistered; extern std::set<CWallet*> setpwalletRegistered;
extern unsigned char pchMessageStart[4];
extern bool fImporting; extern bool fImporting;
extern bool fReindex; extern bool fReindex;
extern bool fBenchmark; extern bool fBenchmark;
@ -353,7 +351,7 @@ public:
// Write index header // Write index header
unsigned int nSize = fileout.GetSerializeSize(*this); unsigned int nSize = fileout.GetSerializeSize(*this);
fileout << FLATDATA(pchMessageStart) << nSize; fileout << FLATDATA(Params().MessageStart()) << nSize;
// Write undo data // Write undo data
long fileOutPos = ftell(fileout); long fileOutPos = ftell(fileout);
@ -692,7 +690,7 @@ public:
// Write index header // Write index header
unsigned int nSize = fileout.GetSerializeSize(*this); unsigned int nSize = fileout.GetSerializeSize(*this);
fileout << FLATDATA(pchMessageStart) << nSize; fileout << FLATDATA(Params().MessageStart()) << nSize;
// Write block // Write block
long fileOutPos = ftell(fileout); long fileOutPos = ftell(fileout);

View file

@ -143,7 +143,8 @@ OBJS= \
obj/bloom.o \ obj/bloom.o \
obj/noui.o \ obj/noui.o \
obj/leveldb.o \ obj/leveldb.o \
obj/txdb.o obj/txdb.o \
obj/chainparams.o
all: bitcoind all: bitcoind

View file

@ -3,6 +3,7 @@
// Distributed under the MIT/X11 software license, see the accompanying // Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "chainparams.h"
#include "db.h" #include "db.h"
#include "net.h" #include "net.h"
#include "core.h" #include "core.h"
@ -80,7 +81,7 @@ void AddOneShot(string strDest)
unsigned short GetListenPort() unsigned short GetListenPort()
{ {
return (unsigned short)(GetArg("-port", GetDefaultPort())); return (unsigned short)(GetArg("-port", Params().GetDefaultPort()));
} }
// find 'best' local address for a particular peer // find 'best' local address for a particular peer
@ -464,7 +465,7 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest)
// Connect // Connect
SOCKET hSocket; SOCKET hSocket;
if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, GetDefaultPort()) : ConnectSocket(addrConnect, hSocket)) if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, Params().GetDefaultPort()) : ConnectSocket(addrConnect, hSocket))
{ {
addrman.Attempt(addrConnect); addrman.Attempt(addrConnect);
@ -1170,53 +1171,31 @@ void MapPort(bool)
// DNS seeds
// Each pair gives a source name and a seed name.
// The first name is used as information source for addrman.
// The second name should resolve to a list of seed addresses.
static const char *strMainNetDNSSeed[][2] = {
{"bitcoin.sipa.be", "seed.bitcoin.sipa.be"},
{"bluematt.me", "dnsseed.bluematt.me"},
{"dashjr.org", "dnsseed.bitcoin.dashjr.org"},
{"xf2.org", "bitseed.xf2.org"},
{NULL, NULL}
};
static const char *strTestNetDNSSeed[][2] = {
{"bitcoin.petertodd.org", "testnet-seed.bitcoin.petertodd.org"},
{"bluematt.me", "testnet-seed.bluematt.me"},
{NULL, NULL}
};
void ThreadDNSAddressSeed() void ThreadDNSAddressSeed()
{ {
static const char *(*strDNSSeed)[2] = fTestNet ? strTestNetDNSSeed : strMainNetDNSSeed; const vector<CDNSSeedData> &vSeeds = Params().DNSSeeds();
int found = 0; int found = 0;
printf("Loading addresses from DNS seeds (could take a while)\n"); printf("Loading addresses from DNS seeds (could take a while)\n");
for (unsigned int seed_idx = 0; strDNSSeed[seed_idx][0] != NULL; seed_idx++) { BOOST_FOREACH(const CDNSSeedData &seed, vSeeds) {
if (HaveNameProxy()) { if (HaveNameProxy()) {
AddOneShot(strDNSSeed[seed_idx][1]); AddOneShot(seed.host);
} else { } else {
vector<CNetAddr> vaddr; vector<CNetAddr> vIPs;
vector<CAddress> vAdd; vector<CAddress> vAdd;
if (LookupHost(strDNSSeed[seed_idx][1], vaddr)) if (LookupHost(seed.host.c_str(), vIPs))
{ {
BOOST_FOREACH(CNetAddr& ip, vaddr) BOOST_FOREACH(CNetAddr& ip, vIPs)
{ {
int nOneDay = 24*3600; int nOneDay = 24*3600;
CAddress addr = CAddress(CService(ip, GetDefaultPort())); CAddress addr = CAddress(CService(ip, Params().GetDefaultPort()));
addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
vAdd.push_back(addr); vAdd.push_back(addr);
found++; found++;
} }
} }
addrman.Add(vAdd, CNetAddr(strDNSSeed[seed_idx][0], true)); addrman.Add(vAdd, CNetAddr(seed.name, true));
} }
} }
@ -1234,85 +1213,6 @@ void ThreadDNSAddressSeed()
unsigned int pnSeed[] =
{
0xe473042e, 0xb177f2ad, 0xd63f3fb2, 0xf864f736, 0x44a23ac7, 0xcf6d9650, 0xd648042e, 0x0536f447,
0x3c654ed0, 0x3e16a5bc, 0xa38e09b0, 0xdfae795b, 0xabfeca5b, 0x94ad7840, 0xf3b9f1c7, 0xbe70e0ad,
0x3bbd09b0, 0x8d0c7dd5, 0x3b2a7332, 0x1a06175e, 0x581f175e, 0xca0d2dcc, 0x0fdbc658, 0xcf591ec7,
0x295a12b2, 0xb4707bce, 0x68bb09b0, 0x4e735747, 0x89709553, 0x05a7814e, 0x5b8ec658, 0x402c5512,
0xe80d0905, 0x17681a5e, 0xc02aa748, 0x9f811741, 0x5f321cb0, 0x23e1ee47, 0xaf7f170c, 0xaa240ab0,
0xedea6257, 0x76106bc1, 0x2cf310cc, 0x08612acb, 0x9c682e4e, 0x8e963c6c, 0x443c795b, 0x22e246b8,
0xfa1f2dcc, 0x90118140, 0x3821042e, 0x33c3fd2e, 0x10046d5b, 0x40d14b3e, 0x7fb8f8ce, 0x67696550,
0xeeecbe58, 0x4f341745, 0x46b8fbd5, 0xc8463932, 0x6b73e862, 0x4c715932, 0x4a6785d5, 0xce3a64c2,
0xde9604c7, 0x9b06884f, 0x18002a45, 0xea9bc345, 0xc4f1c658, 0xe475c1c7, 0xdd3e795b, 0x9722175e,
0x34562f4e, 0x66c46e4e, 0x40bb1243, 0x7d9171d0, 0x17b8dbd5, 0x63cbfd2e, 0x1a08b8d8, 0x6175a73b,
0x228d2660, 0x8627c658, 0x9c566644, 0x38cca5bc, 0x3089de5b, 0x92e25f5d, 0xa393f73f, 0xcc92dc3e,
0x27487446, 0x62cbfd2e, 0x9d983b45, 0xf72a09b0, 0xf75f042e, 0x6434bb6a, 0xb29e77d8, 0x19be4fd9,
0x76443243, 0x9dd72645, 0x694cef43, 0x89c2efd5, 0x5f1c5058, 0x46c6e45b, 0xe1391b40, 0x77ccefd5,
0x472e5a6d, 0x85709553, 0xdd4f5d4c, 0x64ef5a46, 0x7f0ae502, 0xcf08d850, 0x3460042e, 0xeafa2d42,
0x793c9044, 0x9d094746, 0x1ab9b153, 0xbfe9a5bc, 0x34771fb0, 0xb7722e32, 0x1168964b, 0x19b06ab8,
0x19243b25, 0x13188045, 0xb4070905, 0x728ebb5d, 0x44f24ac8, 0xa317fead, 0x642f6a57, 0x3d951f32,
0x3d312e4e, 0xfac4d048, 0xefc4dd50, 0x52b9f1c7, 0xc14d3cc3, 0x0219ea44, 0x3b79d058, 0xfa217242,
0x39c80647, 0xfb697252, 0x1d495a42, 0x0aa81f4e, 0x58249ab8, 0xe6a8e6c3, 0x2bc4dad8, 0x85963c6c,
0xa4ce09b0, 0x2005f536, 0x5cc2703e, 0x1992de43, 0x74e86b4c, 0xe7085653, 0xf5e15a51, 0xb4872b60,
0x29e2b162, 0xa07ea053, 0x8229fd18, 0x4562ec4d, 0x8dec814e, 0x36cfa4cf, 0x96461032, 0x3c8770de,
0xd10a1f5f, 0x95934641, 0x97cd65d0, 0x2e35324a, 0x2566ba1f, 0x1ca1a9d1, 0xb808b8d5, 0xf9a24a5d,
0xafc8d431, 0xe4b8d9b2, 0x0f5321b2, 0x330bc658, 0x74b347ce, 0x972babd5, 0x044f7d4f, 0x06562f4e,
0x8b8d3c6c, 0x3507c658, 0xe4174e4d, 0xf1c009b0, 0x52249ab8, 0x27211772, 0xf6a9ba59, 0x7a391b40,
0x855dc6c0, 0x291f20b2, 0xe29bc345, 0x90963c6c, 0x0af70732, 0x4242a91f, 0x4c531d48, 0xa32df948,
0x627e3044, 0x65be1f54, 0x1a0cbf83, 0x6a443532, 0x8d5f1955, 0xbafa8132, 0x3534bdd5, 0xca019dd9,
0x8a0d9332, 0x5584e7d8, 0x7cd1f25e, 0xeabe3fb2, 0x2945d0d1, 0x46415718, 0x70d6042e, 0x99eb76d0,
0x9ece09b0, 0xb3777418, 0x5e5e91d9, 0x237a3ab0, 0xf512b62e, 0x45dec347, 0x59b7f862, 0x4c443b25,
0x3cc6484b, 0x9a8ec6d1, 0x021eea44, 0xc9483944, 0xfd567e32, 0xfd204bb2, 0xc5330bcc, 0x5202894e,
0xf9e309b0, 0x4cc17557, 0xdb9064ae, 0xe19e77d8, 0x25857f60, 0xeb4a15ad, 0x1f47f554, 0xea4472d9,
0xd20de593, 0xf5733b25, 0x11892b54, 0x5729d35f, 0xe6188cd1, 0x488b132e, 0x541c534a, 0xa8e854ae,
0xa255a66c, 0x33688763, 0xc6629ac6, 0xc20a6265, 0xcd92a059, 0x72029d3b, 0x4c298f5e, 0x51452e4e,
0xbb065058, 0x15fd2dcc, 0xf40c135e, 0x615a0bad, 0x0c6a6805, 0x4971a7ad, 0x17f2a5d5, 0xf8babf47,
0xb61f50ad, 0x4e1451b1, 0xf72d9252, 0x5c2abe58, 0xbd987c61, 0x084ae5cf, 0x20781fb0, 0x38b0f160,
0x18aac705, 0x14f86dc1, 0x5556f481, 0x0a36c144, 0xeb446e4c, 0x2c1c0d6c, 0xbd0ff860, 0x869f92db,
0x36c94f4c, 0x05502444, 0x148fe55b, 0xd5301e59, 0xd57a8f45, 0x110dc04a, 0x8670fc36, 0xee733b25,
0xca56f481, 0x2a5c3bae, 0x844b0905, 0x1e51fe53, 0x0241c244, 0x59c0614e, 0x94e70a55, 0x7312fead,
0xb735be44, 0xa55d0905, 0x2f63962e, 0x14a4e15b, 0x63f8f05c, 0x62d0d262, 0x3cab41ad, 0x87f1b1cb,
0x018da6b8, 0xb3967dd5, 0xcb56f481, 0x685ad718, 0x3b4aeeca, 0x8d106bc1, 0x51180905, 0x72660f48,
0x1521a243, 0x5b56f481, 0x6390e560, 0xdd61464e, 0x58353b25, 0x553fc062, 0x27c45d59, 0xacc62e4e,
0x0d5a1cd9, 0x7f65f442, 0xbdeef660, 0xf1bd1855, 0xf8473cae, 0x13b120b2, 0x442440d0, 0x53fd4352,
0xa305fc57, 0x458be84d, 0x639ce1c3, 0xebaaee47, 0x95e2c247, 0xf056f481, 0x6256f481, 0x1d87c65e,
0x0a453418, 0x5beb175e, 0xd64f1618, 0xc360795b, 0x2fbf5753, 0xa8c58e53, 0x651cec52, 0x9d37b043,
0x124a9758, 0x5242e4a9, 0x89913c6c, 0x880efe2e, 0x2f2f2f0c, 0x72b26751, 0x2896e46d, 0x80f4166c,
0x320d59ad, 0xc50151d0, 0x11a8aa43, 0xccf56057, 0x5fbad118, 0x4719b151, 0x2b5f4bc0, 0x4d7a4a50,
0xad06e047, 0x62ef5a46, 0x5aebde58, 0xdf7aa66c, 0x851acb50, 0x66b9a559, 0x3e9bb153, 0xcc512f2e,
0xc073b08e, 0xd519be58, 0xe981ea4d, 0x12fd50cb, 0x378739ad, 0x06683cae, 0xa22310b2, 0xc185c705,
0x8741b545, 0xa26c8318, 0x22d5bc43, 0x39201ec0, 0x68581e3e, 0xdc9bcf62, 0xd508cc82, 0xb149675b,
0x4c9609b0, 0x84feb84c, 0x08291e2e, 0xfd2253b2, 0x1fd269c1, 0xc9483932, 0x4d641fb0, 0x7d37c918,
0xa9de20ad, 0x77e2d655, 0x6d421b59, 0xd7668f80, 0xced09b62, 0xa9e5a5bc, 0xa4074e18, 0x60fc5ecc,
0x01300148, 0x68062444, 0xb4224847, 0xed3aa443, 0xb772fb43, 0x9f56f481, 0x220dfd18, 0x8e1c3d6c,
0xc44f09b0, 0x7df2bb73, 0xe22fb844, 0xea534242, 0xb6a755d4, 0xa036654b, 0x138ece5b, 0xda65d3c3,
0x955871bc, 0x792124b0, 0xfc82594c, 0x851d494b, 0x2c7aee47, 0x26af46b8, 0x1416252e, 0xa8abb944,
0x36c49d25, 0x674f645d, 0x363646b8, 0x9e1a2942, 0x66d0c154, 0xc6c2a545, 0x3570f2ad, 0xe7d547c7,
0x7d104932, 0x18cb9c18, 0x1dcfa4cf, 0xd156f481, 0x2a02b91f, 0x3eeb3fa8, 0xcac4175e, 0x34146d42,
0x994c4d46, 0x5666f440, 0x85d6713e, 0x5ecb296c, 0x0ea0ae46, 0x87e69f42, 0xc58409b0, 0x1f3436ae,
0x21dc6a57, 0x4ad1cd42, 0xfb8c1a4c, 0x52d3dab2, 0x3769894b, 0xb52f1c62, 0x3677916d, 0x82b3fe57,
0x493d4ac6, 0x9f963c6c, 0x5d91ff60, 0x458e0dad, 0xa49d0947, 0x491a3e18, 0x4aadcd5b, 0x0e46494b,
0x1d1610ad, 0x1a10af5d, 0x4956f481, 0x207a3eae, 0x77e73244, 0xfa3b8742, 0x3261fc36, 0xfcebf536,
0x1662e836, 0xf655f636, 0xa2dbd0ad, 0x23036693, 0x30448432, 0xa2b03463, 0x30730344, 0x8e4a6882,
0x0c50a1cb, 0xc8d8c06b, 0xc9cd6191, 0xf443db50, 0xa9553c50, 0x23145847, 0xc35da66c, 0x29c12a60,
0x55c2b447, 0x7434f75c, 0x61660640, 0xde2a7018, 0xc639494c, 0x1c306fce, 0x19b89244, 0xd29a6462,
0x462cd1b2, 0x29902f44, 0x2817fa53, 0x21a30905, 0x7777ae46, 0x288443a1, 0x7bee5148, 0xc2a8b043,
0xf5c3d35f, 0x2311ef84, 0x57de08a4, 0x6b221bb2, 0xf2625846, 0x4b9e09b0, 0xa24f880e, 0x22b11447,
0xb3a0c744, 0x919e77d8, 0xec8b64ae, 0xff5c8d45, 0x7b15b484, 0x32679a5f, 0xba80b62e, 0x05c25c61,
0x60014746, 0x5e8fb04c, 0xe67c0905, 0x4329c658, 0xac8fe555, 0xf875e647, 0x67406386, 0x35ceea18,
0xbb79484b, 0xd7b9fa62, 0x238209b0, 0x208a1d32, 0x9630995e, 0x039c1318, 0x6e48006c, 0x60582344,
0xadbb0150, 0x853fd462, 0x03772e4e, 0x652ce960, 0x49b630ad, 0x9993af43, 0x3735b34b, 0x548a07d9,
0x55a44aad, 0xa23d1bcc, 0xfdbb2f4e, 0x530b24a0, 0x0a44b451, 0x6827c657, 0x1f66494b, 0x4e680a47,
0x77e7b747, 0xa5eb3fa8, 0x6649764a, 0xd4e76c4b, 0x2c691fb0, 0xf1292e44, 0xc6d6c774, 0x85d23775,
0x28275f4d, 0x259ae46d, 0x02424e81, 0x5f16be58, 0xe707c658, 0x49eae5c7, 0xd5d147ad, 0x9a7abdc3,
0xe8ac7fc7, 0x84ec3aae, 0xc24942d0, 0x294aa318, 0x08ac3d18, 0x8894042e, 0xb24609b0, 0x9bcaab58,
0xc400f712, 0xd5c512b8, 0x2c02cc62, 0x25080fd8, 0xed74a847, 0x18a5ec5e, 0x9850ec6d, 0xf8909758,
0x7f56f481, 0x4496f23c, 0xae27784f, 0xcb7cd93e, 0x06e32860, 0x50b9a84f, 0x3660434a, 0x09161f5f,
0x900486bc, 0x08055459, 0xe7ec1017, 0x7e39494c, 0x4f443b25, 0x14751a8a, 0x717d03d4, 0xbd0e24d8,
0x054b6f56, 0x854c496c, 0xd92a454a, 0xc39bd054, 0x6093614b, 0x9dbad754, 0x5bf0604a, 0x99f22305
};
void DumpAddresses() void DumpAddresses()
{ {
int64 nStart = GetTimeMillis(); int64 nStart = GetTimeMillis();
@ -1374,24 +1274,14 @@ void ThreadOpenConnections()
CSemaphoreGrant grant(*semOutbound); CSemaphoreGrant grant(*semOutbound);
boost::this_thread::interruption_point(); boost::this_thread::interruption_point();
// Add seed nodes if IRC isn't working // Add seed nodes if DNS seeds are all down (an infrastructure attack?).
if (addrman.size()==0 && (GetTime() - nStart > 60) && !fTestNet) if (addrman.size() == 0 && (GetTime() - nStart > 60)) {
{ static bool done = false;
std::vector<CAddress> vAdd; if (!done) {
for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++) printf("Adding fixed seed nodes as DNS doesn't seem to be available.\n");
{ addrman.Add(Params().FixedSeeds(), CNetAddr("127.0.0.1"));
// It'll only connect to one or two seed nodes because once it connects, done = true;
// it'll get a pile of addresses with newer timestamps.
// Seed nodes are given a random 'last seen time' of between one and two
// weeks ago.
const int64 nOneWeek = 7*24*60*60;
struct in_addr ip;
memcpy(&ip, &pnSeed[i], sizeof(ip));
CAddress addr(CService(ip, GetDefaultPort()));
addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
vAdd.push_back(addr);
} }
addrman.Add(vAdd, CNetAddr("127.0.0.1"));
} }
// //
@ -1440,7 +1330,7 @@ void ThreadOpenConnections()
continue; continue;
// do not allow non-default ports, unless after 50 invalid addresses selected already // do not allow non-default ports, unless after 50 invalid addresses selected already
if (addr.GetPort() != GetDefaultPort() && nTries < 50) if (addr.GetPort() != Params().GetDefaultPort() && nTries < 50)
continue; continue;
addrConnect = addr; addrConnect = addr;
@ -1490,7 +1380,7 @@ void ThreadOpenAddedConnections()
BOOST_FOREACH(string& strAddNode, lAddresses) BOOST_FOREACH(string& strAddNode, lAddresses)
{ {
vector<CService> vservNode(0); vector<CService> vservNode(0);
if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fNameLookup, 0)) if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0))
{ {
lservAddressesToAdd.push_back(vservNode); lservAddressesToAdd.push_back(vservNode);
{ {

View file

@ -21,7 +21,7 @@ static const char* ppszTypeName[] =
CMessageHeader::CMessageHeader() CMessageHeader::CMessageHeader()
{ {
memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)); memcpy(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE);
memset(pchCommand, 0, sizeof(pchCommand)); memset(pchCommand, 0, sizeof(pchCommand));
pchCommand[1] = 1; pchCommand[1] = 1;
nMessageSize = -1; nMessageSize = -1;
@ -30,7 +30,7 @@ CMessageHeader::CMessageHeader()
CMessageHeader::CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn) CMessageHeader::CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn)
{ {
memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)); memcpy(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE);
strncpy(pchCommand, pszCommand, COMMAND_SIZE); strncpy(pchCommand, pszCommand, COMMAND_SIZE);
nMessageSize = nMessageSizeIn; nMessageSize = nMessageSizeIn;
nChecksum = 0; nChecksum = 0;
@ -47,7 +47,7 @@ std::string CMessageHeader::GetCommand() const
bool CMessageHeader::IsValid() const bool CMessageHeader::IsValid() const
{ {
// Check start string // Check start string
if (memcmp(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)) != 0) if (memcmp(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0)
return false; return false;
// Check the command string for errors // Check the command string for errors

View file

@ -10,20 +10,12 @@
#ifndef __INCLUDED_PROTOCOL_H__ #ifndef __INCLUDED_PROTOCOL_H__
#define __INCLUDED_PROTOCOL_H__ #define __INCLUDED_PROTOCOL_H__
#include "chainparams.h"
#include "serialize.h" #include "serialize.h"
#include "netbase.h" #include "netbase.h"
#include <string> #include <string>
#include "uint256.h" #include "uint256.h"
extern bool fTestNet;
static inline unsigned short GetDefaultPort(const bool testnet = fTestNet)
{
return testnet ? 18333 : 8333;
}
extern unsigned char pchMessageStart[4];
/** Message header. /** Message header.
* (4) message start. * (4) message start.
* (12) command. * (12) command.
@ -50,7 +42,6 @@ class CMessageHeader
// TODO: make private (improves encapsulation) // TODO: make private (improves encapsulation)
public: public:
enum { enum {
MESSAGE_START_SIZE=sizeof(::pchMessageStart),
COMMAND_SIZE=12, COMMAND_SIZE=12,
MESSAGE_SIZE_SIZE=sizeof(int), MESSAGE_SIZE_SIZE=sizeof(int),
CHECKSUM_SIZE=sizeof(int), CHECKSUM_SIZE=sizeof(int),

View file

@ -5,6 +5,7 @@
#include "addresstablemodel.h" #include "addresstablemodel.h"
#include "transactiontablemodel.h" #include "transactiontablemodel.h"
#include "chainparams.h"
#include "alert.h" #include "alert.h"
#include "main.h" #include "main.h"
#include "checkpoints.h" #include "checkpoints.h"
@ -110,7 +111,7 @@ void ClientModel::updateAlert(const QString &hash, int status)
bool ClientModel::isTestNet() const bool ClientModel::isTestNet() const
{ {
return fTestNet; return TestNet();
} }
bool ClientModel::inInitialBlockDownload() const bool ClientModel::inInitialBlockDownload() const

View file

@ -3,6 +3,7 @@
// Distributed under the MIT/X11 software license, see the accompanying // Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "chainparams.h"
#include "main.h" #include "main.h"
#include "db.h" #include "db.h"
#include "init.h" #include "init.h"
@ -93,7 +94,7 @@ Value getmininginfo(const Array& params, bool fHelp)
obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", -1))); obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", -1)));
obj.push_back(Pair("hashespersec", gethashespersec(params, false))); obj.push_back(Pair("hashespersec", gethashespersec(params, false)));
obj.push_back(Pair("pooledtx", (uint64_t)mempool.size())); obj.push_back(Pair("pooledtx", (uint64_t)mempool.size()));
obj.push_back(Pair("testnet", fTestNet)); obj.push_back(Pair("testnet", TestNet()));
return obj; return obj;
} }

View file

@ -157,7 +157,7 @@ Value getaddednodeinfo(const Array& params, bool fHelp)
BOOST_FOREACH(string& strAddNode, laddedNodes) BOOST_FOREACH(string& strAddNode, laddedNodes)
{ {
vector<CService> vservNode(0); vector<CService> vservNode(0);
if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fNameLookup, 0)) if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0))
laddedAddreses.push_back(make_pair(strAddNode, vservNode)); laddedAddreses.push_back(make_pair(strAddNode, vservNode));
else else
{ {

View file

@ -79,7 +79,7 @@ Value getinfo(const Array& params, bool fHelp)
obj.push_back(Pair("connections", (int)vNodes.size())); obj.push_back(Pair("connections", (int)vNodes.size()));
obj.push_back(Pair("proxy", (proxy.first.IsValid() ? proxy.first.ToStringIPPort() : string()))); obj.push_back(Pair("proxy", (proxy.first.IsValid() ? proxy.first.ToStringIPPort() : string())));
obj.push_back(Pair("difficulty", (double)GetDifficulty())); obj.push_back(Pair("difficulty", (double)GetDifficulty()));
obj.push_back(Pair("testnet", fTestNet)); obj.push_back(Pair("testnet", TestNet()));
obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime())); obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime()));
obj.push_back(Pair("keypoolsize", pwalletMain->GetKeyPoolSize())); obj.push_back(Pair("keypoolsize", pwalletMain->GetKeyPoolSize()));
obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee))); obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee)));

View file

@ -8,6 +8,7 @@
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include "chainparams.h"
#include "main.h" #include "main.h"
#include "wallet.h" #include "wallet.h"
#include "net.h" #include "net.h"
@ -25,7 +26,7 @@ CService ip(uint32_t i)
{ {
struct in_addr s; struct in_addr s;
s.s_addr = i; s.s_addr = i;
return CService(CNetAddr(s), GetDefaultPort()); return CService(CNetAddr(s), Params().GetDefaultPort());
} }
BOOST_AUTO_TEST_SUITE(DoS_tests) BOOST_AUTO_TEST_SUITE(DoS_tests)

View file

@ -108,8 +108,6 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse)
std::vector<unsigned char> result; std::vector<unsigned char> result;
CBitcoinSecret secret; CBitcoinSecret secret;
CBitcoinAddress addr; CBitcoinAddress addr;
// Save global state
bool fTestNet_stored = fTestNet;
BOOST_FOREACH(Value& tv, tests) BOOST_FOREACH(Value& tv, tests)
{ {
@ -125,7 +123,10 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse)
const Object &metadata = test[2].get_obj(); const Object &metadata = test[2].get_obj();
bool isPrivkey = find_value(metadata, "isPrivkey").get_bool(); bool isPrivkey = find_value(metadata, "isPrivkey").get_bool();
bool isTestnet = find_value(metadata, "isTestnet").get_bool(); bool isTestnet = find_value(metadata, "isTestnet").get_bool();
fTestNet = isTestnet; // Override testnet flag if (isTestnet)
SelectParams(CChainParams::TESTNET);
else
SelectParams(CChainParams::MAIN);
if(isPrivkey) if(isPrivkey)
{ {
bool isCompressed = find_value(metadata, "isCompressed").get_bool(); bool isCompressed = find_value(metadata, "isCompressed").get_bool();
@ -156,8 +157,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse)
BOOST_CHECK_MESSAGE(!secret.IsValid(), "IsValid pubkey as privkey:" + strTest); BOOST_CHECK_MESSAGE(!secret.IsValid(), "IsValid pubkey as privkey:" + strTest);
} }
} }
// Restore global state SelectParams(CChainParams::MAIN);
fTestNet = fTestNet_stored;
} }
// Goal: check that generated keys match test vectors // Goal: check that generated keys match test vectors
@ -165,9 +165,6 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen)
{ {
Array tests = read_json("base58_keys_valid.json"); Array tests = read_json("base58_keys_valid.json");
std::vector<unsigned char> result; std::vector<unsigned char> result;
// Save global state
bool fTestNet_stored = fTestNet;
BOOST_FOREACH(Value& tv, tests) BOOST_FOREACH(Value& tv, tests)
{ {
Array test = tv.get_array(); Array test = tv.get_array();
@ -182,7 +179,10 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen)
const Object &metadata = test[2].get_obj(); const Object &metadata = test[2].get_obj();
bool isPrivkey = find_value(metadata, "isPrivkey").get_bool(); bool isPrivkey = find_value(metadata, "isPrivkey").get_bool();
bool isTestnet = find_value(metadata, "isTestnet").get_bool(); bool isTestnet = find_value(metadata, "isTestnet").get_bool();
fTestNet = isTestnet; // Override testnet flag if (isTestnet)
SelectParams(CChainParams::TESTNET);
else
SelectParams(CChainParams::MAIN);
if(isPrivkey) if(isPrivkey)
{ {
bool isCompressed = find_value(metadata, "isCompressed").get_bool(); bool isCompressed = find_value(metadata, "isCompressed").get_bool();
@ -225,8 +225,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen)
CTxDestination nodest = CNoDestination(); CTxDestination nodest = CNoDestination();
BOOST_CHECK(!boost::apply_visitor(CBitcoinAddressVisitor(&dummyAddr), nodest)); BOOST_CHECK(!boost::apply_visitor(CBitcoinAddressVisitor(&dummyAddr), nodest));
// Restore global state SelectParams(CChainParams::MAIN);
fTestNet = fTestNet_stored;
} }
// Goal: check that base58 parsing code is robust against a variety of corrupted data // Goal: check that base58 parsing code is robust against a variety of corrupted data

View file

@ -6,6 +6,7 @@
#include "txdb.h" #include "txdb.h"
#include "main.h" #include "main.h"
#include "hash.h" #include "hash.h"
#include "chainparams.h"
using namespace std; using namespace std;
@ -223,7 +224,7 @@ bool CBlockTreeDB::LoadBlockIndexGuts()
pindexNew->nTx = diskindex.nTx; pindexNew->nTx = diskindex.nTx;
// Watch for genesis block // Watch for genesis block
if (pindexGenesisBlock == NULL && diskindex.GetBlockHash() == hashGenesisBlock) if (pindexGenesisBlock == NULL && diskindex.GetBlockHash() == Params().HashGenesisBlock())
pindexGenesisBlock = pindexNew; pindexGenesisBlock = pindexNew;
if (!pindexNew->CheckIndex()) if (!pindexNew->CheckIndex())

View file

@ -13,6 +13,7 @@
#include <sys/resource.h> #include <sys/resource.h>
#endif #endif
#include "chainparams.h"
#include "util.h" #include "util.h"
#include "sync.h" #include "sync.h"
#include "version.h" #include "version.h"
@ -78,7 +79,6 @@ bool fDaemon = false;
bool fServer = false; bool fServer = false;
bool fCommandLine = false; bool fCommandLine = false;
string strMiscWarning; string strMiscWarning;
bool fTestNet = false;
bool fNoListen = false; bool fNoListen = false;
bool fLogTimestamps = false; bool fLogTimestamps = false;
CMedianFilter<int64> vTimeOffsets(200,0); CMedianFilter<int64> vTimeOffsets(200,0);
@ -1068,8 +1068,8 @@ const boost::filesystem::path &GetDataDir(bool fNetSpecific)
} else { } else {
path = GetDefaultDataDir(); path = GetDefaultDataDir();
} }
if (fNetSpecific && GetBoolArg("-testnet", false)) if (fNetSpecific)
path /= "testnet3"; path /= Params().DataDir();
fs::create_directories(path); fs::create_directories(path);

View file

@ -143,7 +143,6 @@ extern bool fDaemon;
extern bool fServer; extern bool fServer;
extern bool fCommandLine; extern bool fCommandLine;
extern std::string strMiscWarning; extern std::string strMiscWarning;
extern bool fTestNet;
extern bool fNoListen; extern bool fNoListen;
extern bool fLogTimestamps; extern bool fLogTimestamps;
extern volatile bool fReopenDebugLog; extern volatile bool fReopenDebugLog;