lbrycrd/src/test/DoS_tests.cpp

208 lines
6.5 KiB
C++
Raw Normal View History

2015-12-13 17:58:29 +01:00
// Copyright (c) 2011-2015 The Bitcoin Core developers
2014-12-13 05:09:33 +01:00
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
// Unit tests for denial-of-service detection/prevention code
2015-07-05 14:17:46 +02:00
#include "chainparams.h"
#include "keystore.h"
#include "net.h"
#include "net_processing.h"
#include "pow.h"
2014-08-27 17:22:33 +02:00
#include "script/sign.h"
#include "serialize.h"
#include "util.h"
#include "test/test_bitcoin.h"
#include <stdint.h>
#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/foreach.hpp>
#include <boost/test/unit_test.hpp>
2012-02-29 16:14:18 +01:00
// Tests this internal-to-main.cpp method:
extern bool AddOrphanTx(const CTransaction& tx, NodeId peer);
extern void EraseOrphansFor(NodeId peer);
extern unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans);
struct COrphanTx {
CTransaction tx;
NodeId fromPeer;
2016-12-03 04:24:23 +01:00
int64_t nTimeExpire;
};
extern std::map<uint256, COrphanTx> mapOrphanTransactions;
2012-02-29 16:14:18 +01:00
CService ip(uint32_t i)
{
struct in_addr s;
s.s_addr = i;
return CService(CNetAddr(s), Params().GetDefaultPort());
}
2016-04-18 02:20:34 +02:00
static NodeId id = 0;
BOOST_FIXTURE_TEST_SUITE(DoS_tests, TestingSetup)
BOOST_AUTO_TEST_CASE(DoS_banning)
{
connman->ClearBanned();
CAddress addr1(ip(0xa0b0c001), NODE_NONE);
CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 0, 0, "", true);
dummyNode1.SetSendVersion(PROTOCOL_VERSION);
GetNodeSignals().InitializeNode(&dummyNode1, *connman);
2013-11-18 01:25:17 +01:00
dummyNode1.nVersion = 1;
Misbehaving(dummyNode1.GetId(), 100); // Should get banned
2016-05-26 20:26:01 +02:00
SendMessages(&dummyNode1, *connman);
BOOST_CHECK(connman->IsBanned(addr1));
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, 1, "", true);
dummyNode2.SetSendVersion(PROTOCOL_VERSION);
GetNodeSignals().InitializeNode(&dummyNode2, *connman);
2013-11-18 01:25:17 +01:00
dummyNode2.nVersion = 1;
Misbehaving(dummyNode2.GetId(), 50);
2016-05-26 20:26:01 +02:00
SendMessages(&dummyNode2, *connman);
BOOST_CHECK(!connman->IsBanned(addr2)); // 2 not banned yet...
BOOST_CHECK(connman->IsBanned(addr1)); // ... but 1 still should be
2013-11-18 01:25:17 +01:00
Misbehaving(dummyNode2.GetId(), 50);
2016-05-26 20:26:01 +02:00
SendMessages(&dummyNode2, *connman);
BOOST_CHECK(connman->IsBanned(addr2));
}
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, 1, "", true);
dummyNode1.SetSendVersion(PROTOCOL_VERSION);
GetNodeSignals().InitializeNode(&dummyNode1, *connman);
2013-11-18 01:25:17 +01:00
dummyNode1.nVersion = 1;
Misbehaving(dummyNode1.GetId(), 100);
2016-05-26 20:26:01 +02:00
SendMessages(&dummyNode1, *connman);
BOOST_CHECK(!connman->IsBanned(addr1));
2013-11-18 01:25:17 +01:00
Misbehaving(dummyNode1.GetId(), 10);
2016-05-26 20:26:01 +02:00
SendMessages(&dummyNode1, *connman);
BOOST_CHECK(!connman->IsBanned(addr1));
2013-11-18 01:25:17 +01:00
Misbehaving(dummyNode1.GetId(), 1);
2016-05-26 20:26:01 +02:00
SendMessages(&dummyNode1, *connman);
BOOST_CHECK(connman->IsBanned(addr1));
mapArgs.erase("-banscore");
}
BOOST_AUTO_TEST_CASE(DoS_bantime)
{
connman->ClearBanned();
int64_t nStartTime = GetTime();
SetMockTime(nStartTime); // Overrides future calls to GetTime()
CAddress addr(ip(0xa0b0c001), NODE_NONE);
CNode dummyNode(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr, 4, 4, "", true);
dummyNode.SetSendVersion(PROTOCOL_VERSION);
GetNodeSignals().InitializeNode(&dummyNode, *connman);
2013-11-18 01:25:17 +01:00
dummyNode.nVersion = 1;
2013-11-18 01:25:17 +01:00
Misbehaving(dummyNode.GetId(), 100);
2016-05-26 20:26:01 +02:00
SendMessages(&dummyNode, *connman);
BOOST_CHECK(connman->IsBanned(addr));
SetMockTime(nStartTime+60*60);
BOOST_CHECK(connman->IsBanned(addr));
SetMockTime(nStartTime+60*60*24+1);
BOOST_CHECK(!connman->IsBanned(addr));
}
2012-02-29 16:14:18 +01:00
CTransaction RandomOrphan()
{
std::map<uint256, COrphanTx>::iterator it;
it = mapOrphanTransactions.lower_bound(GetRandHash());
2012-02-29 16:14:18 +01:00
if (it == mapOrphanTransactions.end())
it = mapOrphanTransactions.begin();
return it->second.tx;
2012-02-29 16:14:18 +01:00
}
BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
{
CKey key;
key.MakeNewKey(true);
CBasicKeyStore keystore;
keystore.AddKey(key);
// 50 orphan transactions:
for (int i = 0; i < 50; i++)
{
CMutableTransaction tx;
2012-02-29 16:14:18 +01:00
tx.vin.resize(1);
tx.vin[0].prevout.n = 0;
tx.vin[0].prevout.hash = GetRandHash();
2012-02-29 16:14:18 +01:00
tx.vin[0].scriptSig << OP_1;
tx.vout.resize(1);
tx.vout[0].nValue = 1*CENT;
tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID());
2012-02-29 16:14:18 +01:00
AddOrphanTx(tx, i);
2012-02-29 16:14:18 +01:00
}
// ... and 50 that depend on other orphans:
for (int i = 0; i < 50; i++)
{
CTransaction txPrev = RandomOrphan();
CMutableTransaction tx;
2012-02-29 16:14:18 +01:00
tx.vin.resize(1);
tx.vin[0].prevout.n = 0;
tx.vin[0].prevout.hash = txPrev.GetHash();
tx.vout.resize(1);
tx.vout[0].nValue = 1*CENT;
tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID());
2016-03-31 14:54:58 +02:00
SignSignature(keystore, txPrev, tx, 0, SIGHASH_ALL);
2012-02-29 16:14:18 +01:00
AddOrphanTx(tx, i);
2012-02-29 16:14:18 +01:00
}
// This really-big orphan should be ignored:
for (int i = 0; i < 10; i++)
{
CTransaction txPrev = RandomOrphan();
CMutableTransaction tx;
tx.vout.resize(1);
tx.vout[0].nValue = 1*CENT;
tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID());
tx.vin.resize(2777);
for (unsigned int j = 0; j < tx.vin.size(); j++)
{
tx.vin[j].prevout.n = j;
tx.vin[j].prevout.hash = txPrev.GetHash();
}
2016-03-31 14:54:58 +02:00
SignSignature(keystore, txPrev, tx, 0, SIGHASH_ALL);
// Re-use same signature for other inputs
// (they don't have to be valid for this test)
for (unsigned int j = 1; j < tx.vin.size(); j++)
tx.vin[j].scriptSig = tx.vin[0].scriptSig;
BOOST_CHECK(!AddOrphanTx(tx, i));
}
// Test EraseOrphansFor:
for (NodeId i = 0; i < 3; i++)
{
size_t sizeBefore = mapOrphanTransactions.size();
EraseOrphansFor(i);
BOOST_CHECK(mapOrphanTransactions.size() < sizeBefore);
}
2012-02-29 16:14:18 +01:00
// Test LimitOrphanTxSize() function:
LimitOrphanTxSize(40);
BOOST_CHECK(mapOrphanTransactions.size() <= 40);
LimitOrphanTxSize(10);
BOOST_CHECK(mapOrphanTransactions.size() <= 10);
LimitOrphanTxSize(0);
BOOST_CHECK(mapOrphanTransactions.empty());
}
BOOST_AUTO_TEST_SUITE_END()