aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.test.include1
-rw-r--r--src/bitcoin-cli.cpp2
-rw-r--r--src/chainparams.cpp10
-rw-r--r--src/checkpoints.cpp10
-rw-r--r--src/checkpoints.h3
-rw-r--r--src/consensus/params.h1
-rw-r--r--src/init.cpp4
-rw-r--r--src/main.cpp87
-rw-r--r--src/main.h2
-rw-r--r--src/net.cpp32
-rw-r--r--src/net.h12
-rw-r--r--src/test/Checkpoints_tests.cpp27
-rw-r--r--src/test/DoS_tests.cpp8
-rw-r--r--src/test/README.md47
-rw-r--r--src/test/net_tests.cpp4
-rw-r--r--src/wallet/wallet.h6
16 files changed, 139 insertions, 117 deletions
diff --git a/src/Makefile.test.include b/src/Makefile.test.include
index 5ce1bbb896..4e4cca14ca 100644
--- a/src/Makefile.test.include
+++ b/src/Makefile.test.include
@@ -50,7 +50,6 @@ BITCOIN_TESTS =\
test/bip32_tests.cpp \
test/blockencodings_tests.cpp \
test/bloom_tests.cpp \
- test/Checkpoints_tests.cpp \
test/coins_tests.cpp \
test/compress_tests.cpp \
test/crypto_tests.cpp \
diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp
index 2d66448d80..8a2f380e67 100644
--- a/src/bitcoin-cli.cpp
+++ b/src/bitcoin-cli.cpp
@@ -240,7 +240,7 @@ UniValue CallRPC(const string& strMethod, const UniValue& params)
event_base_free(base);
if (response.status == 0)
- throw CConnectionFailed(strprintf("couldn't connect to server (%d %s)", response.error, http_errorstring(response.error)));
+ throw CConnectionFailed(strprintf("couldn't connect to server\n(make sure server is running and you are connecting to the correct RPC port: %d %s)", response.error, http_errorstring(response.error)));
else if (response.status == HTTP_UNAUTHORIZED)
throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)");
else if (response.status >= 400 && response.status != HTTP_BAD_REQUEST && response.status != HTTP_NOT_FOUND && response.status != HTTP_INTERNAL_SERVER_ERROR)
diff --git a/src/chainparams.cpp b/src/chainparams.cpp
index 5850016ae2..a57ab632e4 100644
--- a/src/chainparams.cpp
+++ b/src/chainparams.cpp
@@ -96,6 +96,9 @@ public:
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 1479168000; // November 15th, 2016.
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1510704000; // November 15th, 2017.
+ // The best chain should have at least this much work.
+ consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000002cb971dd56d1c583c20f90");
+
/**
* 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
@@ -191,6 +194,9 @@ public:
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 1462060800; // May 1st 2016
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1493596800; // May 1st 2017
+ // The best chain should have at least this much work.
+ consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000000000198b4def2baa9338d6");
+
pchMessageStart[0] = 0x0b;
pchMessageStart[1] = 0x11;
pchMessageStart[2] = 0x09;
@@ -224,6 +230,7 @@ public:
fRequireStandard = false;
fMineBlocksOnDemand = false;
+
checkpointData = (CCheckpointData) {
boost::assign::map_list_of
( 546, uint256S("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")),
@@ -265,6 +272,9 @@ public:
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 999999999999ULL;
+ // The best chain should have at least this much work.
+ consensus.nMinimumChainWork = uint256S("0x00");
+
pchMessageStart[0] = 0xfa;
pchMessageStart[1] = 0xbf;
pchMessageStart[2] = 0xb5;
diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp
index aefddce464..d22c188c16 100644
--- a/src/checkpoints.cpp
+++ b/src/checkpoints.cpp
@@ -55,16 +55,6 @@ namespace Checkpoints {
return fWorkBefore / (fWorkBefore + fWorkAfter);
}
- int GetTotalBlocksEstimate(const CCheckpointData& data)
- {
- const MapCheckpoints& checkpoints = data.mapCheckpoints;
-
- if (checkpoints.empty())
- return 0;
-
- return checkpoints.rbegin()->first;
- }
-
CBlockIndex* GetLastCheckpoint(const CCheckpointData& data)
{
const MapCheckpoints& checkpoints = data.mapCheckpoints;
diff --git a/src/checkpoints.h b/src/checkpoints.h
index cd25ea5379..04346f35ff 100644
--- a/src/checkpoints.h
+++ b/src/checkpoints.h
@@ -19,9 +19,6 @@ struct CCheckpointData;
namespace Checkpoints
{
-//! Return conservative estimate of total number of blocks, 0 if unknown
-int GetTotalBlocksEstimate(const CCheckpointData& data);
-
//! Returns last CBlockIndex* in mapBlockIndex that is a checkpoint
CBlockIndex* GetLastCheckpoint(const CCheckpointData& data);
diff --git a/src/consensus/params.h b/src/consensus/params.h
index 0e73cace83..20efc68ade 100644
--- a/src/consensus/params.h
+++ b/src/consensus/params.h
@@ -61,6 +61,7 @@ struct Params {
int64_t nPowTargetSpacing;
int64_t nPowTargetTimespan;
int64_t DifficultyAdjustmentInterval() const { return nPowTargetTimespan / nPowTargetSpacing; }
+ uint256 nMinimumChainWork;
};
} // namespace Consensus
diff --git a/src/init.cpp b/src/init.cpp
index 008bb6fae5..31e3efb459 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -1103,6 +1103,10 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
return false;
#endif
// ********************************************************* Step 6: network initialization
+ // Note that we absolutely cannot open any actual connections
+ // until the very end ("start node") as the UTXO/block state
+ // is not yet setup and may end up being set up twice if we
+ // need to reindex later.
assert(!g_connman);
g_connman = std::unique_ptr<CConnman>(new CConnman(GetRand(std::numeric_limits<uint64_t>::max()), GetRand(std::numeric_limits<uint64_t>::max())));
diff --git a/src/main.cpp b/src/main.cpp
index 4cc886afb5..3f706b1503 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -63,7 +63,7 @@ CCriticalSection cs_main;
BlockMap mapBlockIndex;
CChain chainActive;
CBlockIndex *pindexBestHeader = NULL;
-int64_t nTimeBestReceived = 0;
+int64_t nTimeBestReceived = 0; // Used only to inform the wallet of when we last received a block
CWaitableCriticalSection csBestBlock;
CConditionVariable cvBlockChange;
int nScriptCheckThreads = 0;
@@ -691,6 +691,16 @@ CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& loc
CCoinsViewCache *pcoinsTip = NULL;
CBlockTreeDB *pblocktree = NULL;
+enum FlushStateMode {
+ FLUSH_STATE_NONE,
+ FLUSH_STATE_IF_NEEDED,
+ FLUSH_STATE_PERIODIC,
+ FLUSH_STATE_ALWAYS
+};
+
+// See definition for documentation
+bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode);
+
//////////////////////////////////////////////////////////////////////////////
//
// mapOrphanTransactions
@@ -1581,6 +1591,9 @@ bool AcceptToMemoryPoolWithTime(CTxMemPool& pool, CValidationState &state, const
BOOST_FOREACH(const uint256& hashTx, vHashTxToUncache)
pcoinsTip->Uncache(hashTx);
}
+ // After we've (potentially) uncached entries, ensure our coins cache is still within its size limits
+ CValidationState stateDummy;
+ FlushStateToDisk(stateDummy, FLUSH_STATE_PERIODIC);
return res;
}
@@ -1746,13 +1759,14 @@ bool IsInitialBlockDownload()
return false;
if (fImporting || fReindex)
return true;
- if (fCheckpointsEnabled && chainActive.Height() < Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()))
+ if (chainActive.Tip() == NULL)
+ return true;
+ if (chainActive.Tip()->nChainWork < UintToArith256(chainParams.GetConsensus().nMinimumChainWork))
return true;
- bool state = (chainActive.Height() < pindexBestHeader->nHeight - 24 * 6 ||
- std::max(chainActive.Tip()->GetBlockTime(), pindexBestHeader->GetBlockTime()) < GetTime() - nMaxTipAge);
- if (!state)
- latchToFalse.store(true, std::memory_order_relaxed);
- return state;
+ if (chainActive.Tip()->GetBlockTime() < (GetTime() - nMaxTipAge))
+ return true;
+ latchToFalse.store(true, std::memory_order_relaxed);
+ return false;
}
bool fLargeWorkForkFound = false;
@@ -1780,7 +1794,7 @@ void CheckForkWarningConditions()
{
AssertLockHeld(cs_main);
// Before we get past initial download, we cannot reliably alert about forks
- // (we assume we don't get stuck on a fork before the last checkpoint)
+ // (we assume we don't get stuck on a fork before finishing our initial sync)
if (IsInitialBlockDownload())
return;
@@ -2564,13 +2578,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
return true;
}
-enum FlushStateMode {
- FLUSH_STATE_NONE,
- FLUSH_STATE_IF_NEEDED,
- FLUSH_STATE_PERIODIC,
- FLUSH_STATE_ALWAYS
-};
-
/**
* Update the on-disk chain state.
* The caches and indexes are flushed depending on the mode we're called with
@@ -2690,7 +2697,6 @@ void static UpdateTip(CBlockIndex *pindexNew, const CChainParams& chainParams) {
chainActive.SetTip(pindexNew);
// New best block
- nTimeBestReceived = GetTime();
mempool.AddTransactionsUpdated(1);
cvBlockChange.notify_all();
@@ -3675,6 +3681,8 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state
if (ppindex)
*ppindex = pindex;
+ CheckBlockIndex(chainparams.GetConsensus());
+
return true;
}
@@ -3702,6 +3710,11 @@ static bool AcceptBlock(const CBlock& block, CValidationState& state, const CCha
// not process unrequested blocks.
bool fTooFarAhead = (pindex->nHeight > int(chainActive.Height() + MIN_BLOCKS_TO_KEEP));
+ // TODO: Decouple this function from the block download logic by removing fRequested
+ // This requires some new chain datastructure to efficiently look up if a
+ // block is in a chain leading to a candidate for best tip, despite not
+ // being such a candidate itself.
+
// TODO: deal better with return value and error conditions for duplicate
// and unrequested blocks.
if (fAlreadyHave) return true;
@@ -3750,13 +3763,11 @@ bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, C
{
{
LOCK(cs_main);
- bool fRequested = MarkBlockAsReceived(pblock->GetHash());
- fRequested |= fForceProcessing;
// Store to disk
CBlockIndex *pindex = NULL;
bool fNewBlock = false;
- bool ret = AcceptBlock(*pblock, state, chainparams, &pindex, fRequested, dbp, &fNewBlock);
+ bool ret = AcceptBlock(*pblock, state, chainparams, &pindex, fForceProcessing, dbp, &fNewBlock);
if (pindex && pfrom) {
mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId();
if (fNewBlock) pfrom->nLastBlockTime = GetTime();
@@ -4268,6 +4279,9 @@ bool RewindBlockIndex(const CChainParams& params)
return true;
}
+// May NOT be used after any connections are up as much
+// of the peer-processing logic assumes a consistent
+// block index state
void UnloadBlockIndex()
{
LOCK(cs_main);
@@ -4278,18 +4292,12 @@ void UnloadBlockIndex()
mempool.clear();
mapOrphanTransactions.clear();
mapOrphanTransactionsByPrev.clear();
- nSyncStarted = 0;
mapBlocksUnlinked.clear();
vinfoBlockFile.clear();
nLastBlockFile = 0;
nBlockSequenceId = 1;
- mapBlockSource.clear();
- mapBlocksInFlight.clear();
- nPreferredDownload = 0;
setDirtyBlockIndex.clear();
setDirtyFileInfo.clear();
- mapNodeState.clear();
- recentRejects.reset(NULL);
versionbitscache.Clear();
for (int b = 0; b < VERSIONBITS_NUM_BITS; b++) {
warningcache[b].clear();
@@ -4314,9 +4322,6 @@ bool InitBlockIndex(const CChainParams& chainparams)
{
LOCK(cs_main);
- // Initialize global variables that cannot be constructed at startup.
- recentRejects.reset(new CRollingBloomFilter(120000, 0.000001));
-
// Check whether we're already initialized
if (chainActive.Genesis() != NULL)
return true;
@@ -4705,6 +4710,11 @@ std::string GetWarnings(const std::string& strFor)
// blockchain -> download logic notification
//
+PeerLogicValidation::PeerLogicValidation(CConnman* connmanIn) : connman(connmanIn) {
+ // Initialize global variables that cannot be constructed at startup.
+ recentRejects.reset(new CRollingBloomFilter(120000, 0.000001));
+}
+
void PeerLogicValidation::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) {
const int nNewHeight = pindexNew->nHeight;
connman->SetBestHeight(nNewHeight);
@@ -4731,6 +4741,8 @@ void PeerLogicValidation::UpdatedBlockTip(const CBlockIndex *pindexNew, const CB
}
});
}
+
+ nTimeBestReceived = GetTime();
}
void PeerLogicValidation::BlockChecked(const CBlock& block, const CValidationState& state) {
@@ -5689,7 +5701,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
Misbehaving(pfrom->GetId(), nDoS);
}
}
- FlushStateToDisk(state, FLUSH_STATE_PERIODIC);
}
@@ -5825,8 +5836,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
return ProcessMessage(pfrom, NetMsgType::HEADERS, vHeadersMsg, nTimeReceived, chainparams, connman);
}
}
-
- CheckBlockIndex(chainparams.GetConsensus());
}
else if (strCommand == NetMsgType::BLOCKTXN && !fImporting && !fReindex) // Ignore blocks received while importing
@@ -5858,12 +5867,16 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
std::vector<CInv> invs;
invs.push_back(CInv(MSG_BLOCK | GetFetchFlags(pfrom, chainActive.Tip(), chainparams.GetConsensus()), resp.blockhash));
pfrom->PushMessage(NetMsgType::GETDATA, invs);
- } else
+ } else {
+ MarkBlockAsReceived(resp.blockhash); // it is now an empty pointer
fBlockRead = true;
+ }
} // Don't hold cs_main when we call into ProcessNewBlock
if (fBlockRead) {
CValidationState state;
- ProcessNewBlock(state, chainparams, pfrom, &block, false, NULL);
+ // Since we requested this block (it was in mapBlocksInFlight), force it to be processed,
+ // even if it would not be a candidate for new tip (missing previous block, chain not long enough, etc)
+ ProcessNewBlock(state, chainparams, pfrom, &block, true, NULL);
int nDoS;
if (state.IsInvalid(nDoS)) {
assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes
@@ -6019,8 +6032,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
}
}
}
-
- CheckBlockIndex(chainparams.GetConsensus());
}
NotifyHeaderTip();
@@ -6039,6 +6050,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
// Such an unrequested block may still be processed, subject to the
// conditions in AcceptBlock().
bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload();
+ {
+ LOCK(cs_main);
+ // Also always process if we requested the block explicitly, as we may
+ // need it even though it is not a candidate for a new best tip.
+ forceProcessing |= MarkBlockAsReceived(block.GetHash());
+ }
ProcessNewBlock(state, chainparams, pfrom, &block, forceProcessing, NULL);
int nDoS;
if (state.IsInvalid(nDoS)) {
diff --git a/src/main.h b/src/main.h
index 35060e34ab..e80314a64b 100644
--- a/src/main.h
+++ b/src/main.h
@@ -552,7 +552,7 @@ private:
CConnman* connman;
public:
- PeerLogicValidation(CConnman* connmanIn) : connman(connmanIn) {}
+ PeerLogicValidation(CConnman* connmanIn);
virtual void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload);
virtual void BlockChecked(const CBlock& block, const CValidationState& state);
diff --git a/src/net.cpp b/src/net.cpp
index 48ba9588d9..18d25cbcd1 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -64,6 +64,7 @@
const static std::string NET_MESSAGE_COMMAND_OTHER = "*other*";
static const uint64_t RANDOMIZER_ID_NETGROUP = 0x6c0edd8036ef4036ULL; // SHA256("netgroup")[0:8]
+static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE = 0xd93e69e2bbfa5735ULL; // SHA256("localhostnonce")[0:8]
//
// Global state variables
//
@@ -389,7 +390,10 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
addrman.Attempt(addrConnect, fCountFailure);
// Add node
- CNode* pnode = new CNode(GetNewNodeId(), nLocalServices, GetBestHeight(), hSocket, addrConnect, CalculateKeyedNetGroup(addrConnect), pszDest ? pszDest : "", false);
+ NodeId id = GetNewNodeId();
+ uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize();
+ CNode* pnode = new CNode(id, nLocalServices, GetBestHeight(), hSocket, addrConnect, CalculateKeyedNetGroup(addrConnect), nonce, pszDest ? pszDest : "", false);
+
GetNodeSignals().InitializeNode(pnode->GetId(), pnode);
pnode->AddRef();
@@ -1024,7 +1028,10 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
}
}
- CNode* pnode = new CNode(GetNewNodeId(), nLocalServices, GetBestHeight(), hSocket, addr, CalculateKeyedNetGroup(addr), "", true);
+ NodeId id = GetNewNodeId();
+ uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize();
+
+ CNode* pnode = new CNode(id, nLocalServices, GetBestHeight(), hSocket, addr, CalculateKeyedNetGroup(addr), nonce, "", true);
GetNodeSignals().InitializeNode(pnode->GetId(), pnode);
pnode->AddRef();
pnode->fWhitelisted = whitelisted;
@@ -2118,7 +2125,11 @@ bool CConnman::Start(boost::thread_group& threadGroup, CScheduler& scheduler, st
if (pnodeLocalHost == NULL) {
CNetAddr local;
LookupHost("127.0.0.1", local, false);
- pnodeLocalHost = new CNode(GetNewNodeId(), nLocalServices, GetBestHeight(), INVALID_SOCKET, CAddress(CService(local, 0), nLocalServices), 0);
+
+ NodeId id = GetNewNodeId();
+ uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize();
+
+ pnodeLocalHost = new CNode(id, nLocalServices, GetBestHeight(), INVALID_SOCKET, CAddress(CService(local, 0), nLocalServices), 0, nonce);
GetNodeSignals().InitializeNode(pnodeLocalHost->GetId(), pnodeLocalHost);
}
@@ -2509,12 +2520,17 @@ void CNode::Fuzz(int nChance)
unsigned int CConnman::GetReceiveFloodSize() const { return nReceiveFloodSize; }
unsigned int CConnman::GetSendBufferSize() const{ return nSendBufferMaxSize; }
-CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress& addrIn, uint64_t nKeyedNetGroupIn, const std::string& addrNameIn, bool fInboundIn) :
+CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress& addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const std::string& addrNameIn, bool fInboundIn) :
ssSend(SER_NETWORK, INIT_PROTO_VERSION),
addr(addrIn),
+ fInbound(fInboundIn),
+ id(idIn),
nKeyedNetGroup(nKeyedNetGroupIn),
addrKnown(5000, 0.001),
- filterInventoryKnown(50000, 0.000001)
+ filterInventoryKnown(50000, 0.000001),
+ nLocalHostNonce(nLocalHostNonceIn),
+ nLocalServices(nLocalServicesIn),
+ nMyStartingHeight(nMyStartingHeightIn)
{
nServices = NODE_NONE;
nServicesExpected = NODE_NONE;
@@ -2533,7 +2549,6 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn
fOneShot = false;
fClient = false; // set by version message
fFeeler = false;
- fInbound = fInboundIn;
fNetworkNode = false;
fSuccessfullyConnected = false;
fDisconnect = false;
@@ -2562,12 +2577,7 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn
minFeeFilter = 0;
lastSentFeeFilter = 0;
nextSendTimeFeeFilter = 0;
- id = idIn;
nOptimisticBytesWritten = 0;
- nLocalServices = nLocalServicesIn;
-
- GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
- nMyStartingHeight = nMyStartingHeightIn;
BOOST_FOREACH(const std::string &msg, getAllNetMessageTypes())
mapRecvBytesPerMsgCmd[msg] = 0;
diff --git a/src/net.h b/src/net.h
index 58b492e592..bfce516237 100644
--- a/src/net.h
+++ b/src/net.h
@@ -589,7 +589,7 @@ public:
bool fFeeler; // If true this node is being used as a short lived feeler.
bool fOneShot;
bool fClient;
- bool fInbound;
+ const bool fInbound;
bool fNetworkNode;
bool fSuccessfullyConnected;
bool fDisconnect;
@@ -603,7 +603,7 @@ public:
CCriticalSection cs_filter;
CBloomFilter* pfilter;
int nRefCount;
- NodeId id;
+ const NodeId id;
const uint64_t nKeyedNetGroup;
protected:
@@ -669,7 +669,7 @@ public:
CAmount lastSentFeeFilter;
int64_t nextSendTimeFeeFilter;
- CNode(NodeId id, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, const std::string &addrNameIn = "", bool fInboundIn = false);
+ CNode(NodeId id, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const std::string &addrNameIn = "", bool fInboundIn = false);
~CNode();
private:
@@ -677,10 +677,10 @@ private:
void operator=(const CNode&);
- uint64_t nLocalHostNonce;
+ const uint64_t nLocalHostNonce;
// Services offered to this peer
- ServiceFlags nLocalServices;
- int nMyStartingHeight;
+ const ServiceFlags nLocalServices;
+ const int nMyStartingHeight;
public:
NodeId GetId() const {
diff --git a/src/test/Checkpoints_tests.cpp b/src/test/Checkpoints_tests.cpp
deleted file mode 100644
index 1b7d368e13..0000000000
--- a/src/test/Checkpoints_tests.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2011-2015 The Bitcoin Core developers
-// Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-//
-// Unit tests for block-chain checkpoints
-//
-
-#include "checkpoints.h"
-
-#include "uint256.h"
-#include "test/test_bitcoin.h"
-#include "chainparams.h"
-
-#include <boost/test/unit_test.hpp>
-
-using namespace std;
-
-BOOST_FIXTURE_TEST_SUITE(Checkpoints_tests, BasicTestingSetup)
-
-BOOST_AUTO_TEST_CASE(sanity)
-{
- const CCheckpointData& checkpoints = Params(CBaseChainParams::MAIN).Checkpoints();
- BOOST_CHECK(Checkpoints::GetTotalBlocksEstimate(checkpoints) >= 134444);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp
index 97abeb7211..4aa7166815 100644
--- a/src/test/DoS_tests.cpp
+++ b/src/test/DoS_tests.cpp
@@ -48,7 +48,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning)
{
connman->ClearBanned();
CAddress addr1(ip(0xa0b0c001), NODE_NONE);
- CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 0, "", true);
+ CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 0, 0, "", true);
GetNodeSignals().InitializeNode(dummyNode1.GetId(), &dummyNode1);
dummyNode1.nVersion = 1;
Misbehaving(dummyNode1.GetId(), 100); // Should get banned
@@ -57,7 +57,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning)
BOOST_CHECK(!connman->IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different IP, not banned
CAddress addr2(ip(0xa0b0c002), NODE_NONE);
- CNode dummyNode2(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr2, 1, "", true);
+ CNode dummyNode2(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr2, 1, 1, "", true);
GetNodeSignals().InitializeNode(dummyNode2.GetId(), &dummyNode2);
dummyNode2.nVersion = 1;
Misbehaving(dummyNode2.GetId(), 50);
@@ -74,7 +74,7 @@ BOOST_AUTO_TEST_CASE(DoS_banscore)
connman->ClearBanned();
mapArgs["-banscore"] = "111"; // because 11 is my favorite number
CAddress addr1(ip(0xa0b0c001), NODE_NONE);
- CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 3, "", true);
+ CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 3, 1, "", true);
GetNodeSignals().InitializeNode(dummyNode1.GetId(), &dummyNode1);
dummyNode1.nVersion = 1;
Misbehaving(dummyNode1.GetId(), 100);
@@ -96,7 +96,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime)
SetMockTime(nStartTime); // Overrides future calls to GetTime()
CAddress addr(ip(0xa0b0c001), NODE_NONE);
- CNode dummyNode(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr, 4, "", true);
+ CNode dummyNode(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr, 4, 4, "", true);
GetNodeSignals().InitializeNode(dummyNode.GetId(), &dummyNode);
dummyNode.nVersion = 1;
diff --git a/src/test/README.md b/src/test/README.md
index 3afdefe5fc..8f99804e10 100644
--- a/src/test/README.md
+++ b/src/test/README.md
@@ -1,4 +1,36 @@
-# Notes
+### Compiling/running unit tests
+
+Unit tests will be automatically compiled if dependencies were met in `./configure`
+and tests weren't explicitly disabled.
+
+After configuring, they can be run with `make check`.
+
+To run the bitcoind tests manually, launch `src/test/test_bitcoin`.
+
+To add more bitcoind tests, add `BOOST_AUTO_TEST_CASE` functions to the existing
+.cpp files in the `test/` directory or add new .cpp files that
+implement new BOOST_AUTO_TEST_SUITE sections.
+
+To run the bitcoin-qt tests manually, launch `src/qt/test/test_bitcoin-qt`
+
+To add more bitcoin-qt tests, add them to the `src/qt/test/` directory and
+the `src/qt/test/test_main.cpp` file.
+
+### Running individual tests
+
+test_bitcoin has some built-in command-line arguments; for
+example, to run just the getarg_tests verbosely:
+
+ test_bitcoin --log_level=all --run_test=getarg_tests
+
+... or to run just the doubledash test:
+
+ test_bitcoin --run_test=getarg_tests/doubledash
+
+Run `test_bitcoin --help` for the full list.
+
+### Note on adding test cases
+
The sources in this directory are unit test cases. Boost includes a
unit testing framework, and since bitcoin already uses boost, it makes
sense to simply use this framework rather than require developers to
@@ -19,17 +51,6 @@ For further reading, I found the following website to be helpful in
explaining how the boost unit test framework works:
[http://www.alittlemadness.com/2009/03/31/c-unit-testing-with-boosttest/](http://www.alittlemadness.com/2009/03/31/c-unit-testing-with-boosttest/).
-test_bitcoin has some built-in command-line arguments; for
-example, to run just the getarg_tests verbosely:
-
- test_bitcoin --log_level=all --run_test=getarg_tests
-
-... or to run just the doubledash test:
-
- test_bitcoin --run_test=getarg_tests/doubledash
-
-Run `test_bitcoin --help` for the full list.
-
### bitcoin-util-test.py
The test directory also contains the bitcoin-util-test.py tool, which tests bitcoin utils (currently just bitcoin-tx). This test gets run automatically during the `make check` build process. It is also possible to run the test manually from the src directory:
@@ -37,4 +58,4 @@ The test directory also contains the bitcoin-util-test.py tool, which tests bitc
```
test/bitcoin-util-test.py --srcdir=[current directory]
-``` \ No newline at end of file
+```
diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp
index f4b5768693..e0460109d5 100644
--- a/src/test/net_tests.cpp
+++ b/src/test/net_tests.cpp
@@ -164,12 +164,12 @@ BOOST_AUTO_TEST_CASE(cnode_simple_test)
bool fInboundIn = false;
// Test that fFeeler is false by default.
- CNode* pnode1 = new CNode(id++, NODE_NETWORK, height, hSocket, addr, 0, pszDest, fInboundIn);
+ CNode* pnode1 = new CNode(id++, NODE_NETWORK, height, hSocket, addr, 0, 0, pszDest, fInboundIn);
BOOST_CHECK(pnode1->fInbound == false);
BOOST_CHECK(pnode1->fFeeler == false);
fInboundIn = true;
- CNode* pnode2 = new CNode(id++, NODE_NETWORK, height, hSocket, addr, 1, pszDest, fInboundIn);
+ CNode* pnode2 = new CNode(id++, NODE_NETWORK, height, hSocket, addr, 1, 1, pszDest, fInboundIn);
BOOST_CHECK(pnode2->fInbound == true);
BOOST_CHECK(pnode2->fFeeler == false);
}
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index d7d1f5513a..57b17d87ad 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -54,7 +54,7 @@ static const bool DEFAULT_SPEND_ZEROCONF_CHANGE = true;
//! Default for -sendfreetransactions
static const bool DEFAULT_SEND_FREE_TRANSACTIONS = false;
//! -txconfirmtarget default
-static const unsigned int DEFAULT_TX_CONFIRM_TARGET = 2;
+static const unsigned int DEFAULT_TX_CONFIRM_TARGET = 6;
//! -walletrbf default
static const bool DEFAULT_WALLET_RBF = false;
//! Largest (in bytes) free transaction we're willing to create
@@ -134,7 +134,7 @@ struct CRecipient
typedef std::map<std::string, std::string> mapValue_t;
-static void ReadOrderPos(int64_t& nOrderPos, mapValue_t& mapValue)
+static inline void ReadOrderPos(int64_t& nOrderPos, mapValue_t& mapValue)
{
if (!mapValue.count("n"))
{
@@ -145,7 +145,7 @@ static void ReadOrderPos(int64_t& nOrderPos, mapValue_t& mapValue)
}
-static void WriteOrderPos(const int64_t& nOrderPos, mapValue_t& mapValue)
+static inline void WriteOrderPos(const int64_t& nOrderPos, mapValue_t& mapValue)
{
if (nOrderPos == -1)
return;