Document assumptions that are being made to avoid NULL pointer dereferences
[bitcoinplatinum.git] / src / test / DoS_tests.cpp
blobffbeeb7d918614c265172b2d936c74e8b5c7e747
1 // Copyright (c) 2011-2016 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 // Unit tests for denial-of-service detection/prevention code
7 #include "chainparams.h"
8 #include "keystore.h"
9 #include "net.h"
10 #include "net_processing.h"
11 #include "pow.h"
12 #include "script/sign.h"
13 #include "serialize.h"
14 #include "util.h"
15 #include "validation.h"
17 #include "test/test_bitcoin.h"
19 #include <stdint.h>
21 #include <boost/test/unit_test.hpp>
23 // Tests these internal-to-net_processing.cpp methods:
24 extern bool AddOrphanTx(const CTransactionRef& tx, NodeId peer);
25 extern void EraseOrphansFor(NodeId peer);
26 extern unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans);
27 struct COrphanTx {
28 CTransactionRef tx;
29 NodeId fromPeer;
30 int64_t nTimeExpire;
32 extern std::map<uint256, COrphanTx> mapOrphanTransactions;
34 CService ip(uint32_t i)
36 struct in_addr s;
37 s.s_addr = i;
38 return CService(CNetAddr(s), Params().GetDefaultPort());
41 static NodeId id = 0;
43 BOOST_FIXTURE_TEST_SUITE(DoS_tests, TestingSetup)
45 BOOST_AUTO_TEST_CASE(DoS_banning)
47 std::atomic<bool> interruptDummy(false);
49 connman->ClearBanned();
50 CAddress addr1(ip(0xa0b0c001), NODE_NONE);
51 CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 0, 0, CAddress(), "", true);
52 dummyNode1.SetSendVersion(PROTOCOL_VERSION);
53 GetNodeSignals().InitializeNode(&dummyNode1, *connman);
54 dummyNode1.nVersion = 1;
55 dummyNode1.fSuccessfullyConnected = true;
56 Misbehaving(dummyNode1.GetId(), 100); // Should get banned
57 SendMessages(&dummyNode1, *connman, interruptDummy);
58 BOOST_CHECK(connman->IsBanned(addr1));
59 BOOST_CHECK(!connman->IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different IP, not banned
61 CAddress addr2(ip(0xa0b0c002), NODE_NONE);
62 CNode dummyNode2(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr2, 1, 1, CAddress(), "", true);
63 dummyNode2.SetSendVersion(PROTOCOL_VERSION);
64 GetNodeSignals().InitializeNode(&dummyNode2, *connman);
65 dummyNode2.nVersion = 1;
66 dummyNode2.fSuccessfullyConnected = true;
67 Misbehaving(dummyNode2.GetId(), 50);
68 SendMessages(&dummyNode2, *connman, interruptDummy);
69 BOOST_CHECK(!connman->IsBanned(addr2)); // 2 not banned yet...
70 BOOST_CHECK(connman->IsBanned(addr1)); // ... but 1 still should be
71 Misbehaving(dummyNode2.GetId(), 50);
72 SendMessages(&dummyNode2, *connman, interruptDummy);
73 BOOST_CHECK(connman->IsBanned(addr2));
76 BOOST_AUTO_TEST_CASE(DoS_banscore)
78 std::atomic<bool> interruptDummy(false);
80 connman->ClearBanned();
81 gArgs.ForceSetArg("-banscore", "111"); // because 11 is my favorite number
82 CAddress addr1(ip(0xa0b0c001), NODE_NONE);
83 CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 3, 1, CAddress(), "", true);
84 dummyNode1.SetSendVersion(PROTOCOL_VERSION);
85 GetNodeSignals().InitializeNode(&dummyNode1, *connman);
86 dummyNode1.nVersion = 1;
87 dummyNode1.fSuccessfullyConnected = true;
88 Misbehaving(dummyNode1.GetId(), 100);
89 SendMessages(&dummyNode1, *connman, interruptDummy);
90 BOOST_CHECK(!connman->IsBanned(addr1));
91 Misbehaving(dummyNode1.GetId(), 10);
92 SendMessages(&dummyNode1, *connman, interruptDummy);
93 BOOST_CHECK(!connman->IsBanned(addr1));
94 Misbehaving(dummyNode1.GetId(), 1);
95 SendMessages(&dummyNode1, *connman, interruptDummy);
96 BOOST_CHECK(connman->IsBanned(addr1));
97 gArgs.ForceSetArg("-banscore", std::to_string(DEFAULT_BANSCORE_THRESHOLD));
100 BOOST_AUTO_TEST_CASE(DoS_bantime)
102 std::atomic<bool> interruptDummy(false);
104 connman->ClearBanned();
105 int64_t nStartTime = GetTime();
106 SetMockTime(nStartTime); // Overrides future calls to GetTime()
108 CAddress addr(ip(0xa0b0c001), NODE_NONE);
109 CNode dummyNode(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr, 4, 4, CAddress(), "", true);
110 dummyNode.SetSendVersion(PROTOCOL_VERSION);
111 GetNodeSignals().InitializeNode(&dummyNode, *connman);
112 dummyNode.nVersion = 1;
113 dummyNode.fSuccessfullyConnected = true;
115 Misbehaving(dummyNode.GetId(), 100);
116 SendMessages(&dummyNode, *connman, interruptDummy);
117 BOOST_CHECK(connman->IsBanned(addr));
119 SetMockTime(nStartTime+60*60);
120 BOOST_CHECK(connman->IsBanned(addr));
122 SetMockTime(nStartTime+60*60*24+1);
123 BOOST_CHECK(!connman->IsBanned(addr));
126 CTransactionRef RandomOrphan()
128 std::map<uint256, COrphanTx>::iterator it;
129 it = mapOrphanTransactions.lower_bound(InsecureRand256());
130 if (it == mapOrphanTransactions.end())
131 it = mapOrphanTransactions.begin();
132 return it->second.tx;
135 BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
137 CKey key;
138 key.MakeNewKey(true);
139 CBasicKeyStore keystore;
140 keystore.AddKey(key);
142 // 50 orphan transactions:
143 for (int i = 0; i < 50; i++)
145 CMutableTransaction tx;
146 tx.vin.resize(1);
147 tx.vin[0].prevout.n = 0;
148 tx.vin[0].prevout.hash = InsecureRand256();
149 tx.vin[0].scriptSig << OP_1;
150 tx.vout.resize(1);
151 tx.vout[0].nValue = 1*CENT;
152 tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID());
154 AddOrphanTx(MakeTransactionRef(tx), i);
157 // ... and 50 that depend on other orphans:
158 for (int i = 0; i < 50; i++)
160 CTransactionRef txPrev = RandomOrphan();
162 CMutableTransaction tx;
163 tx.vin.resize(1);
164 tx.vin[0].prevout.n = 0;
165 tx.vin[0].prevout.hash = txPrev->GetHash();
166 tx.vout.resize(1);
167 tx.vout[0].nValue = 1*CENT;
168 tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID());
169 SignSignature(keystore, *txPrev, tx, 0, SIGHASH_ALL);
171 AddOrphanTx(MakeTransactionRef(tx), i);
174 // This really-big orphan should be ignored:
175 for (int i = 0; i < 10; i++)
177 CTransactionRef txPrev = RandomOrphan();
179 CMutableTransaction tx;
180 tx.vout.resize(1);
181 tx.vout[0].nValue = 1*CENT;
182 tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID());
183 tx.vin.resize(2777);
184 for (unsigned int j = 0; j < tx.vin.size(); j++)
186 tx.vin[j].prevout.n = j;
187 tx.vin[j].prevout.hash = txPrev->GetHash();
189 SignSignature(keystore, *txPrev, tx, 0, SIGHASH_ALL);
190 // Re-use same signature for other inputs
191 // (they don't have to be valid for this test)
192 for (unsigned int j = 1; j < tx.vin.size(); j++)
193 tx.vin[j].scriptSig = tx.vin[0].scriptSig;
195 BOOST_CHECK(!AddOrphanTx(MakeTransactionRef(tx), i));
198 // Test EraseOrphansFor:
199 for (NodeId i = 0; i < 3; i++)
201 size_t sizeBefore = mapOrphanTransactions.size();
202 EraseOrphansFor(i);
203 BOOST_CHECK(mapOrphanTransactions.size() < sizeBefore);
206 // Test LimitOrphanTxSize() function:
207 LimitOrphanTxSize(40);
208 BOOST_CHECK(mapOrphanTransactions.size() <= 40);
209 LimitOrphanTxSize(10);
210 BOOST_CHECK(mapOrphanTransactions.size() <= 10);
211 LimitOrphanTxSize(0);
212 BOOST_CHECK(mapOrphanTransactions.empty());
215 BOOST_AUTO_TEST_SUITE_END()