net: Disallow sending messages until the version handshake is complete
[bitcoinplatinum.git] / src / test / DoS_tests.cpp
bloba8f09ba6aef7a74d5b6c4a46fd2fa2803ec92fce
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/assign/list_of.hpp> // for 'map_list_of()'
22 #include <boost/date_time/posix_time/posix_time_types.hpp>
23 #include <boost/foreach.hpp>
24 #include <boost/test/unit_test.hpp>
26 // Tests this internal-to-main.cpp method:
27 extern bool AddOrphanTx(const CTransactionRef& tx, NodeId peer);
28 extern void EraseOrphansFor(NodeId peer);
29 extern unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans);
30 struct COrphanTx {
31 CTransactionRef tx;
32 NodeId fromPeer;
33 int64_t nTimeExpire;
35 extern std::map<uint256, COrphanTx> mapOrphanTransactions;
37 CService ip(uint32_t i)
39 struct in_addr s;
40 s.s_addr = i;
41 return CService(CNetAddr(s), Params().GetDefaultPort());
44 static NodeId id = 0;
46 BOOST_FIXTURE_TEST_SUITE(DoS_tests, TestingSetup)
48 BOOST_AUTO_TEST_CASE(DoS_banning)
50 std::atomic<bool> interruptDummy(false);
52 connman->ClearBanned();
53 CAddress addr1(ip(0xa0b0c001), NODE_NONE);
54 CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 0, 0, "", true);
55 dummyNode1.SetSendVersion(PROTOCOL_VERSION);
56 GetNodeSignals().InitializeNode(&dummyNode1, *connman);
57 dummyNode1.nVersion = 1;
58 dummyNode1.fSuccessfullyConnected = true;
59 Misbehaving(dummyNode1.GetId(), 100); // Should get banned
60 SendMessages(&dummyNode1, *connman, interruptDummy);
61 BOOST_CHECK(connman->IsBanned(addr1));
62 BOOST_CHECK(!connman->IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different IP, not banned
64 CAddress addr2(ip(0xa0b0c002), NODE_NONE);
65 CNode dummyNode2(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr2, 1, 1, "", true);
66 dummyNode2.SetSendVersion(PROTOCOL_VERSION);
67 GetNodeSignals().InitializeNode(&dummyNode2, *connman);
68 dummyNode2.nVersion = 1;
69 dummyNode2.fSuccessfullyConnected = true;
70 Misbehaving(dummyNode2.GetId(), 50);
71 SendMessages(&dummyNode2, *connman, interruptDummy);
72 BOOST_CHECK(!connman->IsBanned(addr2)); // 2 not banned yet...
73 BOOST_CHECK(connman->IsBanned(addr1)); // ... but 1 still should be
74 Misbehaving(dummyNode2.GetId(), 50);
75 SendMessages(&dummyNode2, *connman, interruptDummy);
76 BOOST_CHECK(connman->IsBanned(addr2));
79 BOOST_AUTO_TEST_CASE(DoS_banscore)
81 std::atomic<bool> interruptDummy(false);
83 connman->ClearBanned();
84 ForceSetArg("-banscore", "111"); // because 11 is my favorite number
85 CAddress addr1(ip(0xa0b0c001), NODE_NONE);
86 CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 3, 1, "", true);
87 dummyNode1.SetSendVersion(PROTOCOL_VERSION);
88 GetNodeSignals().InitializeNode(&dummyNode1, *connman);
89 dummyNode1.nVersion = 1;
90 dummyNode1.fSuccessfullyConnected = true;
91 Misbehaving(dummyNode1.GetId(), 100);
92 SendMessages(&dummyNode1, *connman, interruptDummy);
93 BOOST_CHECK(!connman->IsBanned(addr1));
94 Misbehaving(dummyNode1.GetId(), 10);
95 SendMessages(&dummyNode1, *connman, interruptDummy);
96 BOOST_CHECK(!connman->IsBanned(addr1));
97 Misbehaving(dummyNode1.GetId(), 1);
98 SendMessages(&dummyNode1, *connman, interruptDummy);
99 BOOST_CHECK(connman->IsBanned(addr1));
100 ForceSetArg("-banscore", std::to_string(DEFAULT_BANSCORE_THRESHOLD));
103 BOOST_AUTO_TEST_CASE(DoS_bantime)
105 std::atomic<bool> interruptDummy(false);
107 connman->ClearBanned();
108 int64_t nStartTime = GetTime();
109 SetMockTime(nStartTime); // Overrides future calls to GetTime()
111 CAddress addr(ip(0xa0b0c001), NODE_NONE);
112 CNode dummyNode(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr, 4, 4, "", true);
113 dummyNode.SetSendVersion(PROTOCOL_VERSION);
114 GetNodeSignals().InitializeNode(&dummyNode, *connman);
115 dummyNode.nVersion = 1;
116 dummyNode.fSuccessfullyConnected = true;
118 Misbehaving(dummyNode.GetId(), 100);
119 SendMessages(&dummyNode, *connman, interruptDummy);
120 BOOST_CHECK(connman->IsBanned(addr));
122 SetMockTime(nStartTime+60*60);
123 BOOST_CHECK(connman->IsBanned(addr));
125 SetMockTime(nStartTime+60*60*24+1);
126 BOOST_CHECK(!connman->IsBanned(addr));
129 CTransactionRef RandomOrphan()
131 std::map<uint256, COrphanTx>::iterator it;
132 it = mapOrphanTransactions.lower_bound(GetRandHash());
133 if (it == mapOrphanTransactions.end())
134 it = mapOrphanTransactions.begin();
135 return it->second.tx;
138 BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
140 CKey key;
141 key.MakeNewKey(true);
142 CBasicKeyStore keystore;
143 keystore.AddKey(key);
145 // 50 orphan transactions:
146 for (int i = 0; i < 50; i++)
148 CMutableTransaction tx;
149 tx.vin.resize(1);
150 tx.vin[0].prevout.n = 0;
151 tx.vin[0].prevout.hash = GetRandHash();
152 tx.vin[0].scriptSig << OP_1;
153 tx.vout.resize(1);
154 tx.vout[0].nValue = 1*CENT;
155 tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID());
157 AddOrphanTx(MakeTransactionRef(tx), i);
160 // ... and 50 that depend on other orphans:
161 for (int i = 0; i < 50; i++)
163 CTransactionRef txPrev = RandomOrphan();
165 CMutableTransaction tx;
166 tx.vin.resize(1);
167 tx.vin[0].prevout.n = 0;
168 tx.vin[0].prevout.hash = txPrev->GetHash();
169 tx.vout.resize(1);
170 tx.vout[0].nValue = 1*CENT;
171 tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID());
172 SignSignature(keystore, *txPrev, tx, 0, SIGHASH_ALL);
174 AddOrphanTx(MakeTransactionRef(tx), i);
177 // This really-big orphan should be ignored:
178 for (int i = 0; i < 10; i++)
180 CTransactionRef txPrev = RandomOrphan();
182 CMutableTransaction tx;
183 tx.vout.resize(1);
184 tx.vout[0].nValue = 1*CENT;
185 tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID());
186 tx.vin.resize(2777);
187 for (unsigned int j = 0; j < tx.vin.size(); j++)
189 tx.vin[j].prevout.n = j;
190 tx.vin[j].prevout.hash = txPrev->GetHash();
192 SignSignature(keystore, *txPrev, tx, 0, SIGHASH_ALL);
193 // Re-use same signature for other inputs
194 // (they don't have to be valid for this test)
195 for (unsigned int j = 1; j < tx.vin.size(); j++)
196 tx.vin[j].scriptSig = tx.vin[0].scriptSig;
198 BOOST_CHECK(!AddOrphanTx(MakeTransactionRef(tx), i));
201 // Test EraseOrphansFor:
202 for (NodeId i = 0; i < 3; i++)
204 size_t sizeBefore = mapOrphanTransactions.size();
205 EraseOrphansFor(i);
206 BOOST_CHECK(mapOrphanTransactions.size() < sizeBefore);
209 // Test LimitOrphanTxSize() function:
210 LimitOrphanTxSize(40);
211 BOOST_CHECK(mapOrphanTransactions.size() <= 40);
212 LimitOrphanTxSize(10);
213 BOOST_CHECK(mapOrphanTransactions.size() <= 10);
214 LimitOrphanTxSize(0);
215 BOOST_CHECK(mapOrphanTransactions.empty());
218 BOOST_AUTO_TEST_SUITE_END()