Merge pull request #3276 from sipa/nodestate

Add main-specific node state & move ban score
This commit is contained in:
Gavin Andresen 2013-12-08 23:33:24 -08:00
commit 7202d9d9bf
8 changed files with 158 additions and 48 deletions

View File

@ -120,6 +120,7 @@ void Shutdown()
GenerateBitcoins(false, NULL, 0); GenerateBitcoins(false, NULL, 0);
#endif #endif
StopNode(); StopNode();
UnregisterNodeSignals(GetNodeSignals());
{ {
LOCK(cs_main); LOCK(cs_main);
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET

View File

@ -153,17 +153,66 @@ void SyncWithWallets(const uint256 &hash, const CTransaction &tx, const CBlock *
// Registration of network node signals. // Registration of network node signals.
// //
int static GetHeight() namespace {
// Maintain validation-specific state about nodes, protected by cs_main, instead
// by CNode's own locks. This simplifies asynchronous operation, where
// processing of incoming data is done after the ProcessMessage call returns,
// and we're no longer holding the node's locks.
struct CNodeState {
int nMisbehavior;
bool fShouldBan;
std::string name;
CNodeState() {
nMisbehavior = 0;
fShouldBan = false;
}
};
map<NodeId, CNodeState> mapNodeState;
// Requires cs_main.
CNodeState *State(NodeId pnode) {
map<NodeId, CNodeState>::iterator it = mapNodeState.find(pnode);
if (it == mapNodeState.end())
return NULL;
return &it->second;
}
int GetHeight()
{ {
LOCK(cs_main); LOCK(cs_main);
return chainActive.Height(); return chainActive.Height();
} }
void InitializeNode(NodeId nodeid, const CNode *pnode) {
LOCK(cs_main);
CNodeState &state = mapNodeState.insert(std::make_pair(nodeid, CNodeState())).first->second;
state.name = pnode->addrName;
}
void FinalizeNode(NodeId nodeid) {
LOCK(cs_main);
mapNodeState.erase(nodeid);
}
}
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats) {
LOCK(cs_main);
CNodeState *state = State(nodeid);
if (state == NULL)
return false;
stats.nMisbehavior = state->nMisbehavior;
return true;
}
void RegisterNodeSignals(CNodeSignals& nodeSignals) void RegisterNodeSignals(CNodeSignals& nodeSignals)
{ {
nodeSignals.GetHeight.connect(&GetHeight); nodeSignals.GetHeight.connect(&GetHeight);
nodeSignals.ProcessMessages.connect(&ProcessMessages); nodeSignals.ProcessMessages.connect(&ProcessMessages);
nodeSignals.SendMessages.connect(&SendMessages); nodeSignals.SendMessages.connect(&SendMessages);
nodeSignals.InitializeNode.connect(&InitializeNode);
nodeSignals.FinalizeNode.connect(&FinalizeNode);
} }
void UnregisterNodeSignals(CNodeSignals& nodeSignals) void UnregisterNodeSignals(CNodeSignals& nodeSignals)
@ -171,6 +220,8 @@ void UnregisterNodeSignals(CNodeSignals& nodeSignals)
nodeSignals.GetHeight.disconnect(&GetHeight); nodeSignals.GetHeight.disconnect(&GetHeight);
nodeSignals.ProcessMessages.disconnect(&ProcessMessages); nodeSignals.ProcessMessages.disconnect(&ProcessMessages);
nodeSignals.SendMessages.disconnect(&SendMessages); nodeSignals.SendMessages.disconnect(&SendMessages);
nodeSignals.InitializeNode.disconnect(&InitializeNode);
nodeSignals.FinalizeNode.disconnect(&FinalizeNode);
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -2915,6 +2966,23 @@ bool static AlreadyHave(const CInv& inv)
} }
void Misbehaving(NodeId pnode, int howmuch)
{
if (howmuch == 0)
return;
CNodeState *state = State(pnode);
if (state == NULL)
return;
state->nMisbehavior += howmuch;
if (state->nMisbehavior >= GetArg("-banscore", 100))
{
LogPrintf("Misbehaving: %s (%d -> %d) BAN THRESHOLD EXCEEDED\n", state->name.c_str(), state->nMisbehavior-howmuch, state->nMisbehavior);
state->fShouldBan = true;
} else
LogPrintf("Misbehaving: %s (%d -> %d)\n", state->name.c_str(), state->nMisbehavior-howmuch, state->nMisbehavior);
}
void static ProcessGetData(CNode* pfrom) void static ProcessGetData(CNode* pfrom)
{ {
@ -3048,7 +3116,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
if (pfrom->nVersion != 0) if (pfrom->nVersion != 0)
{ {
pfrom->PushMessage("reject", strCommand, REJECT_DUPLICATE, string("Duplicate version message")); pfrom->PushMessage("reject", strCommand, REJECT_DUPLICATE, string("Duplicate version message"));
pfrom->Misbehaving(1); Misbehaving(pfrom->GetId(), 1);
return false; return false;
} }
@ -3153,7 +3221,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
else if (pfrom->nVersion == 0) else if (pfrom->nVersion == 0)
{ {
// Must have a version message before anything else // Must have a version message before anything else
pfrom->Misbehaving(1); Misbehaving(pfrom->GetId(), 1);
return false; return false;
} }
@ -3174,7 +3242,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
return true; return true;
if (vAddr.size() > 1000) if (vAddr.size() > 1000)
{ {
pfrom->Misbehaving(20); Misbehaving(pfrom->GetId(), 20);
return error("message addr size() = %"PRIszu"", vAddr.size()); return error("message addr size() = %"PRIszu"", vAddr.size());
} }
@ -3237,7 +3305,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
vRecv >> vInv; vRecv >> vInv;
if (vInv.size() > MAX_INV_SZ) if (vInv.size() > MAX_INV_SZ)
{ {
pfrom->Misbehaving(20); Misbehaving(pfrom->GetId(), 20);
return error("message inv size() = %"PRIszu"", vInv.size()); return error("message inv size() = %"PRIszu"", vInv.size());
} }
@ -3288,7 +3356,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
vRecv >> vInv; vRecv >> vInv;
if (vInv.size() > MAX_INV_SZ) if (vInv.size() > MAX_INV_SZ)
{ {
pfrom->Misbehaving(20); Misbehaving(pfrom->GetId(), 20);
return error("message getdata size() = %"PRIszu"", vInv.size()); return error("message getdata size() = %"PRIszu"", vInv.size());
} }
@ -3461,7 +3529,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
pfrom->PushMessage("reject", strCommand, state.GetRejectCode(), pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
state.GetRejectReason(), inv.hash); state.GetRejectReason(), inv.hash);
if (nDoS > 0) if (nDoS > 0)
pfrom->Misbehaving(nDoS); Misbehaving(pfrom->GetId(), nDoS);
} }
} }
@ -3488,7 +3556,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
pfrom->PushMessage("reject", strCommand, state.GetRejectCode(), pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
state.GetRejectReason(), inv.hash); state.GetRejectReason(), inv.hash);
if (nDoS > 0) if (nDoS > 0)
pfrom->Misbehaving(nDoS); Misbehaving(pfrom->GetId(), nDoS);
} }
} }
@ -3631,7 +3699,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
// This isn't a Misbehaving(100) (immediate ban) because the // This isn't a Misbehaving(100) (immediate ban) because the
// peer might be an older or different implementation with // peer might be an older or different implementation with
// a different signature key, etc. // a different signature key, etc.
pfrom->Misbehaving(10); Misbehaving(pfrom->GetId(), 10);
} }
} }
} }
@ -3644,7 +3712,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
if (!filter.IsWithinSizeConstraints()) if (!filter.IsWithinSizeConstraints())
// There is no excuse for sending a too-large filter // There is no excuse for sending a too-large filter
pfrom->Misbehaving(100); Misbehaving(pfrom->GetId(), 100);
else else
{ {
LOCK(pfrom->cs_filter); LOCK(pfrom->cs_filter);
@ -3665,13 +3733,13 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
// and thus, the maximum size any matched object can have) in a filteradd message // and thus, the maximum size any matched object can have) in a filteradd message
if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE) if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE)
{ {
pfrom->Misbehaving(100); Misbehaving(pfrom->GetId(), 100);
} else { } else {
LOCK(pfrom->cs_filter); LOCK(pfrom->cs_filter);
if (pfrom->pfilter) if (pfrom->pfilter)
pfrom->pfilter->insert(vData); pfrom->pfilter->insert(vData);
else else
pfrom->Misbehaving(100); Misbehaving(pfrom->GetId(), 100);
} }
} }
@ -3936,6 +4004,16 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
if (!lockMain) if (!lockMain)
return true; return true;
if (State(pto->GetId())->fShouldBan) {
if (pto->addr.IsLocal())
LogPrintf("Warning: not banning local node %s!\n", pto->addr.ToString().c_str());
else {
pto->fDisconnect = true;
CNode::Ban(pto->addr);
}
State(pto->GetId())->fShouldBan = false;
}
// Start block sync // Start block sync
if (pto->fStartSync && !fImporting && !fReindex) { if (pto->fStartSync && !fImporting && !fReindex) {
pto->fStartSync = false; pto->fStartSync = false;

View File

@ -110,6 +110,7 @@ class CTxUndo;
class CScriptCheck; class CScriptCheck;
class CValidationState; class CValidationState;
class CWalletInterface; class CWalletInterface;
struct CNodeStateStats;
struct CBlockTemplate; struct CBlockTemplate;
@ -182,6 +183,8 @@ CBlockIndex * InsertBlockIndex(uint256 hash);
bool VerifySignature(const CCoins& txFrom, const CTransaction& txTo, unsigned int nIn, unsigned int flags, int nHashType); bool VerifySignature(const CCoins& txFrom, const CTransaction& txTo, unsigned int nIn, unsigned int flags, int nHashType);
/** Abort with a message */ /** Abort with a message */
bool AbortNode(const std::string &msg); bool AbortNode(const std::string &msg);
/** Get statistics from node state */
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats);
/** (try to) add transaction to memory pool **/ /** (try to) add transaction to memory pool **/
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,
@ -194,6 +197,10 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
struct CNodeStateStats {
int nMisbehavior;
};
struct CDiskBlockPos struct CDiskBlockPos
{ {
int nFile; int nFile;

View File

@ -80,6 +80,9 @@ CCriticalSection cs_setservAddNodeAddresses;
vector<std::string> vAddedNodes; vector<std::string> vAddedNodes;
CCriticalSection cs_vAddedNodes; CCriticalSection cs_vAddedNodes;
NodeId nLastNodeId = 0;
CCriticalSection cs_nLastNodeId;
static CSemaphore *semOutbound = NULL; static CSemaphore *semOutbound = NULL;
// Signals for message handling // Signals for message handling
@ -581,35 +584,21 @@ bool CNode::IsBanned(CNetAddr ip)
return fResult; return fResult;
} }
bool CNode::Misbehaving(int howmuch) bool CNode::Ban(const CNetAddr &addr) {
{
if (addr.IsLocal())
{
LogPrintf("Warning: Local node %s misbehaving (delta: %d)!\n", addrName.c_str(), howmuch);
return false;
}
nMisbehavior += howmuch;
if (nMisbehavior >= GetArg("-banscore", 100))
{
int64_t banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban int64_t banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
LogPrintf("Misbehaving: %s (%d -> %d) DISCONNECTING\n", addr.ToString().c_str(), nMisbehavior-howmuch, nMisbehavior);
{ {
LOCK(cs_setBanned); LOCK(cs_setBanned);
if (setBanned[addr] < banTime) if (setBanned[addr] < banTime)
setBanned[addr] = banTime; setBanned[addr] = banTime;
} }
CloseSocketDisconnect();
return true; return true;
} else
LogPrintf("Misbehaving: %s (%d -> %d)\n", addr.ToString().c_str(), nMisbehavior-howmuch, nMisbehavior);
return false;
} }
#undef X #undef X
#define X(name) stats.name = name #define X(name) stats.name = name
void CNode::copyStats(CNodeStats &stats) void CNode::copyStats(CNodeStats &stats)
{ {
stats.nodeid = this->GetId();
X(nServices); X(nServices);
X(nLastSend); X(nLastSend);
X(nLastRecv); X(nLastRecv);
@ -619,7 +608,6 @@ void CNode::copyStats(CNodeStats &stats)
X(cleanSubVer); X(cleanSubVer);
X(fInbound); X(fInbound);
X(nStartingHeight); X(nStartingHeight);
X(nMisbehavior);
X(nSendBytes); X(nSendBytes);
X(nRecvBytes); X(nRecvBytes);
stats.fSyncNode = (this == pnodeSync); stats.fSyncNode = (this == pnodeSync);

View File

@ -57,14 +57,19 @@ void StartNode(boost::thread_group& threadGroup);
bool StopNode(); bool StopNode();
void SocketSendData(CNode *pnode); void SocketSendData(CNode *pnode);
typedef int NodeId;
// Signals for message handling // Signals for message handling
struct CNodeSignals struct CNodeSignals
{ {
boost::signals2::signal<int ()> GetHeight; boost::signals2::signal<int ()> GetHeight;
boost::signals2::signal<bool (CNode*)> ProcessMessages; boost::signals2::signal<bool (CNode*)> ProcessMessages;
boost::signals2::signal<bool (CNode*, bool)> SendMessages; boost::signals2::signal<bool (CNode*, bool)> SendMessages;
boost::signals2::signal<void (NodeId, const CNode*)> InitializeNode;
boost::signals2::signal<void (NodeId)> FinalizeNode;
}; };
CNodeSignals& GetNodeSignals(); CNodeSignals& GetNodeSignals();
@ -109,12 +114,14 @@ extern limitedmap<CInv, int64_t> mapAlreadyAskedFor;
extern std::vector<std::string> vAddedNodes; extern std::vector<std::string> vAddedNodes;
extern CCriticalSection cs_vAddedNodes; extern CCriticalSection cs_vAddedNodes;
extern NodeId nLastNodeId;
extern CCriticalSection cs_nLastNodeId;
class CNodeStats class CNodeStats
{ {
public: public:
NodeId nodeid;
uint64_t nServices; uint64_t nServices;
int64_t nLastSend; int64_t nLastSend;
int64_t nLastRecv; int64_t nLastRecv;
@ -124,7 +131,6 @@ public:
std::string cleanSubVer; std::string cleanSubVer;
bool fInbound; bool fInbound;
int nStartingHeight; int nStartingHeight;
int nMisbehavior;
uint64_t nSendBytes; uint64_t nSendBytes;
uint64_t nRecvBytes; uint64_t nRecvBytes;
bool fSyncNode; bool fSyncNode;
@ -223,13 +229,13 @@ public:
CCriticalSection cs_filter; CCriticalSection cs_filter;
CBloomFilter* pfilter; CBloomFilter* pfilter;
int nRefCount; int nRefCount;
NodeId id;
protected: protected:
// Denial-of-service detection/prevention // Denial-of-service detection/prevention
// Key is IP address, value is banned-until-time // Key is IP address, value is banned-until-time
static std::map<CNetAddr, int64_t> setBanned; static std::map<CNetAddr, int64_t> setBanned;
static CCriticalSection cs_setBanned; static CCriticalSection cs_setBanned;
int nMisbehavior;
// Basic fuzz-testing // Basic fuzz-testing
void Fuzz(int nChance); // modifies ssSend void Fuzz(int nChance); // modifies ssSend
@ -289,7 +295,6 @@ public:
nStartingHeight = -1; nStartingHeight = -1;
fStartSync = false; fStartSync = false;
fGetAddr = false; fGetAddr = false;
nMisbehavior = 0;
fRelayTxes = false; fRelayTxes = false;
setInventoryKnown.max_size(SendBufferSize() / 1000); setInventoryKnown.max_size(SendBufferSize() / 1000);
pfilter = new CBloomFilter(); pfilter = new CBloomFilter();
@ -298,9 +303,16 @@ public:
nPingUsecTime = 0; nPingUsecTime = 0;
fPingQueued = false; fPingQueued = false;
{
LOCK(cs_nLastNodeId);
id = nLastNodeId++;
}
// Be shy and don't send version until we hear // Be shy and don't send version until we hear
if (hSocket != INVALID_SOCKET && !fInbound) if (hSocket != INVALID_SOCKET && !fInbound)
PushVersion(); PushVersion();
GetNodeSignals().InitializeNode(GetId(), this);
} }
~CNode() ~CNode()
@ -312,6 +324,7 @@ public:
} }
if (pfilter) if (pfilter)
delete pfilter; delete pfilter;
GetNodeSignals().FinalizeNode(GetId());
} }
private: private:
@ -326,6 +339,9 @@ private:
public: public:
NodeId GetId() const {
return id;
}
int GetRefCount() int GetRefCount()
{ {
@ -673,7 +689,7 @@ public:
// new code. // new code.
static void ClearBanned(); // needed for unit testing static void ClearBanned(); // needed for unit testing
static bool IsBanned(CNetAddr ip); static bool IsBanned(CNetAddr ip);
bool Misbehaving(int howmuch); // 1 == a little, 100 == a lot static bool Ban(const CNetAddr &ip);
void copyStats(CNodeStats &stats); void copyStats(CNodeStats &stats);
// Network stats // Network stats

View File

@ -2,6 +2,9 @@
// 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 "rpcserver.h" #include "rpcserver.h"
#include "main.h"
#include "net.h" #include "net.h"
#include "netbase.h" #include "netbase.h"
#include "protocol.h" #include "protocol.h"
@ -114,7 +117,8 @@ Value getpeerinfo(const Array& params, bool fHelp)
BOOST_FOREACH(const CNodeStats& stats, vstats) { BOOST_FOREACH(const CNodeStats& stats, vstats) {
Object obj; Object obj;
CNodeStateStats statestats;
bool fStateStats = GetNodeStateStats(stats.nodeid, statestats);
obj.push_back(Pair("addr", stats.addrName)); obj.push_back(Pair("addr", stats.addrName));
if (!(stats.addrLocal.empty())) if (!(stats.addrLocal.empty()))
obj.push_back(Pair("addrlocal", stats.addrLocal)); obj.push_back(Pair("addrlocal", stats.addrLocal));
@ -134,7 +138,9 @@ Value getpeerinfo(const Array& params, bool fHelp)
obj.push_back(Pair("subver", stats.cleanSubVer)); obj.push_back(Pair("subver", stats.cleanSubVer));
obj.push_back(Pair("inbound", stats.fInbound)); obj.push_back(Pair("inbound", stats.fInbound));
obj.push_back(Pair("startingheight", stats.nStartingHeight)); obj.push_back(Pair("startingheight", stats.nStartingHeight));
obj.push_back(Pair("banscore", stats.nMisbehavior)); if (fStateStats) {
obj.push_back(Pair("banscore", statestats.nMisbehavior));
}
if (stats.fSyncNode) if (stats.fSyncNode)
obj.push_back(Pair("syncnode", true)); obj.push_back(Pair("syncnode", true));

View File

@ -21,6 +21,7 @@
// Tests this internal-to-main.cpp method: // Tests this internal-to-main.cpp method:
extern bool AddOrphanTx(const CTransaction& tx); extern bool AddOrphanTx(const CTransaction& tx);
extern unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans); extern unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans);
extern void Misbehaving(NodeId nodeid, int howmuch);
extern std::map<uint256, CTransaction> mapOrphanTransactions; extern std::map<uint256, CTransaction> mapOrphanTransactions;
extern std::map<uint256, std::set<uint256> > mapOrphanTransactionsByPrev; extern std::map<uint256, std::set<uint256> > mapOrphanTransactionsByPrev;
@ -38,16 +39,21 @@ BOOST_AUTO_TEST_CASE(DoS_banning)
CNode::ClearBanned(); CNode::ClearBanned();
CAddress addr1(ip(0xa0b0c001)); CAddress addr1(ip(0xa0b0c001));
CNode dummyNode1(INVALID_SOCKET, addr1, "", true); CNode dummyNode1(INVALID_SOCKET, addr1, "", true);
dummyNode1.Misbehaving(100); // Should get banned dummyNode1.nVersion = 1;
Misbehaving(dummyNode1.GetId(), 100); // Should get banned
SendMessages(&dummyNode1, false);
BOOST_CHECK(CNode::IsBanned(addr1)); BOOST_CHECK(CNode::IsBanned(addr1));
BOOST_CHECK(!CNode::IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different IP, not banned BOOST_CHECK(!CNode::IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different IP, not banned
CAddress addr2(ip(0xa0b0c002)); CAddress addr2(ip(0xa0b0c002));
CNode dummyNode2(INVALID_SOCKET, addr2, "", true); CNode dummyNode2(INVALID_SOCKET, addr2, "", true);
dummyNode2.Misbehaving(50); dummyNode2.nVersion = 1;
Misbehaving(dummyNode2.GetId(), 50);
SendMessages(&dummyNode2, false);
BOOST_CHECK(!CNode::IsBanned(addr2)); // 2 not banned yet... BOOST_CHECK(!CNode::IsBanned(addr2)); // 2 not banned yet...
BOOST_CHECK(CNode::IsBanned(addr1)); // ... but 1 still should be BOOST_CHECK(CNode::IsBanned(addr1)); // ... but 1 still should be
dummyNode2.Misbehaving(50); Misbehaving(dummyNode2.GetId(), 50);
SendMessages(&dummyNode2, false);
BOOST_CHECK(CNode::IsBanned(addr2)); BOOST_CHECK(CNode::IsBanned(addr2));
} }
@ -57,11 +63,15 @@ BOOST_AUTO_TEST_CASE(DoS_banscore)
mapArgs["-banscore"] = "111"; // because 11 is my favorite number mapArgs["-banscore"] = "111"; // because 11 is my favorite number
CAddress addr1(ip(0xa0b0c001)); CAddress addr1(ip(0xa0b0c001));
CNode dummyNode1(INVALID_SOCKET, addr1, "", true); CNode dummyNode1(INVALID_SOCKET, addr1, "", true);
dummyNode1.Misbehaving(100); dummyNode1.nVersion = 1;
Misbehaving(dummyNode1.GetId(), 100);
SendMessages(&dummyNode1, false);
BOOST_CHECK(!CNode::IsBanned(addr1)); BOOST_CHECK(!CNode::IsBanned(addr1));
dummyNode1.Misbehaving(10); Misbehaving(dummyNode1.GetId(), 10);
SendMessages(&dummyNode1, false);
BOOST_CHECK(!CNode::IsBanned(addr1)); BOOST_CHECK(!CNode::IsBanned(addr1));
dummyNode1.Misbehaving(1); Misbehaving(dummyNode1.GetId(), 1);
SendMessages(&dummyNode1, false);
BOOST_CHECK(CNode::IsBanned(addr1)); BOOST_CHECK(CNode::IsBanned(addr1));
mapArgs.erase("-banscore"); mapArgs.erase("-banscore");
} }
@ -74,8 +84,10 @@ BOOST_AUTO_TEST_CASE(DoS_bantime)
CAddress addr(ip(0xa0b0c001)); CAddress addr(ip(0xa0b0c001));
CNode dummyNode(INVALID_SOCKET, addr, "", true); CNode dummyNode(INVALID_SOCKET, addr, "", true);
dummyNode.nVersion = 1;
dummyNode.Misbehaving(100); Misbehaving(dummyNode.GetId(), 100);
SendMessages(&dummyNode, false);
BOOST_CHECK(CNode::IsBanned(addr)); BOOST_CHECK(CNode::IsBanned(addr));
SetMockTime(nStartTime+60*60); SetMockTime(nStartTime+60*60);

View File

@ -47,11 +47,13 @@ struct TestingSetup {
nScriptCheckThreads = 3; nScriptCheckThreads = 3;
for (int i=0; i < nScriptCheckThreads-1; i++) for (int i=0; i < nScriptCheckThreads-1; i++)
threadGroup.create_thread(&ThreadScriptCheck); threadGroup.create_thread(&ThreadScriptCheck);
RegisterNodeSignals(GetNodeSignals());
} }
~TestingSetup() ~TestingSetup()
{ {
threadGroup.interrupt_all(); threadGroup.interrupt_all();
threadGroup.join_all(); threadGroup.join_all();
UnregisterNodeSignals(GetNodeSignals());
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
delete pwalletMain; delete pwalletMain;
pwalletMain = NULL; pwalletMain = NULL;