]> Git Repo - VerusCoin.git/blob - src/test/DoS_tests.cpp
Merge pull request #4868
[VerusCoin.git] / src / test / DoS_tests.cpp
1 // Copyright (c) 2011-2014 The Bitcoin Core developers
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5 //
6 // Unit tests for denial-of-service detection/prevention code
7 //
8
9
10
11 #include "keystore.h"
12 #include "main.h"
13 #include "net.h"
14 #include "pow.h"
15 #include "script/sign.h"
16 #include "serialize.h"
17 #include "util.h"
18
19 #include <stdint.h>
20
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>
25
26 // Tests this internal-to-main.cpp method:
27 extern bool AddOrphanTx(const CTransaction& tx);
28 extern unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans);
29 extern std::map<uint256, CTransaction> mapOrphanTransactions;
30 extern std::map<uint256, std::set<uint256> > mapOrphanTransactionsByPrev;
31
32 CService ip(uint32_t i)
33 {
34     struct in_addr s;
35     s.s_addr = i;
36     return CService(CNetAddr(s), Params().GetDefaultPort());
37 }
38
39 BOOST_AUTO_TEST_SUITE(DoS_tests)
40
41 BOOST_AUTO_TEST_CASE(DoS_banning)
42 {
43     CNode::ClearBanned();
44     CAddress addr1(ip(0xa0b0c001));
45     CNode dummyNode1(INVALID_SOCKET, addr1, "", true);
46     dummyNode1.nVersion = 1;
47     Misbehaving(dummyNode1.GetId(), 100); // Should get banned
48     SendMessages(&dummyNode1, false);
49     BOOST_CHECK(CNode::IsBanned(addr1));
50     BOOST_CHECK(!CNode::IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different IP, not banned
51
52     CAddress addr2(ip(0xa0b0c002));
53     CNode dummyNode2(INVALID_SOCKET, addr2, "", true);
54     dummyNode2.nVersion = 1;
55     Misbehaving(dummyNode2.GetId(), 50);
56     SendMessages(&dummyNode2, false);
57     BOOST_CHECK(!CNode::IsBanned(addr2)); // 2 not banned yet...
58     BOOST_CHECK(CNode::IsBanned(addr1));  // ... but 1 still should be
59     Misbehaving(dummyNode2.GetId(), 50);
60     SendMessages(&dummyNode2, false);
61     BOOST_CHECK(CNode::IsBanned(addr2));
62 }
63
64 BOOST_AUTO_TEST_CASE(DoS_banscore)
65 {
66     CNode::ClearBanned();
67     mapArgs["-banscore"] = "111"; // because 11 is my favorite number
68     CAddress addr1(ip(0xa0b0c001));
69     CNode dummyNode1(INVALID_SOCKET, addr1, "", true);
70     dummyNode1.nVersion = 1;
71     Misbehaving(dummyNode1.GetId(), 100);
72     SendMessages(&dummyNode1, false);
73     BOOST_CHECK(!CNode::IsBanned(addr1));
74     Misbehaving(dummyNode1.GetId(), 10);
75     SendMessages(&dummyNode1, false);
76     BOOST_CHECK(!CNode::IsBanned(addr1));
77     Misbehaving(dummyNode1.GetId(), 1);
78     SendMessages(&dummyNode1, false);
79     BOOST_CHECK(CNode::IsBanned(addr1));
80     mapArgs.erase("-banscore");
81 }
82
83 BOOST_AUTO_TEST_CASE(DoS_bantime)
84 {
85     CNode::ClearBanned();
86     int64_t nStartTime = GetTime();
87     SetMockTime(nStartTime); // Overrides future calls to GetTime()
88
89     CAddress addr(ip(0xa0b0c001));
90     CNode dummyNode(INVALID_SOCKET, addr, "", true);
91     dummyNode.nVersion = 1;
92
93     Misbehaving(dummyNode.GetId(), 100);
94     SendMessages(&dummyNode, false);
95     BOOST_CHECK(CNode::IsBanned(addr));
96
97     SetMockTime(nStartTime+60*60);
98     BOOST_CHECK(CNode::IsBanned(addr));
99
100     SetMockTime(nStartTime+60*60*24+1);
101     BOOST_CHECK(!CNode::IsBanned(addr));
102 }
103
104 static bool CheckNBits(unsigned int nbits1, int64_t time1, unsigned int nbits2, int64_t time2)\
105 {
106     if (time1 > time2)
107         return CheckNBits(nbits2, time2, nbits1, time1);
108     int64_t deltaTime = time2-time1;
109
110     return CheckMinWork(nbits2, nbits1, deltaTime);
111 }
112
113 BOOST_AUTO_TEST_CASE(DoS_checknbits)
114 {
115     using namespace boost::assign; // for 'map_list_of()'
116
117     // Timestamps,nBits from the bitcoin block chain.
118     // These are the block-chain checkpoint blocks
119     typedef std::map<int64_t, unsigned int> BlockData;
120     BlockData chainData =
121         map_list_of(1239852051,486604799)(1262749024,486594666)
122         (1279305360,469854461)(1280200847,469830746)(1281678674,469809688)
123         (1296207707,453179945)(1302624061,453036989)(1309640330,437004818)
124         (1313172719,436789733);
125
126     // Make sure CheckNBits considers every combination of block-chain-lock-in-points
127     // "sane":
128     BOOST_FOREACH(const BlockData::value_type& i, chainData)
129     {
130         BOOST_FOREACH(const BlockData::value_type& j, chainData)
131         {
132             BOOST_CHECK(CheckNBits(i.second, i.first, j.second, j.first));
133         }
134     }
135
136     // Test a couple of insane combinations:
137     BlockData::value_type firstcheck = *(chainData.begin());
138     BlockData::value_type lastcheck = *(chainData.rbegin());
139
140     // First checkpoint difficulty at or a while after the last checkpoint time should fail when
141     // compared to last checkpoint
142     BOOST_CHECK(!CheckNBits(firstcheck.second, lastcheck.first+60*10, lastcheck.second, lastcheck.first));
143     BOOST_CHECK(!CheckNBits(firstcheck.second, lastcheck.first+60*60*24*14, lastcheck.second, lastcheck.first));
144
145     // ... but OK if enough time passed for difficulty to adjust downward:
146     BOOST_CHECK(CheckNBits(firstcheck.second, lastcheck.first+60*60*24*365*4, lastcheck.second, lastcheck.first));
147 }
148
149 CTransaction RandomOrphan()
150 {
151     std::map<uint256, CTransaction>::iterator it;
152     it = mapOrphanTransactions.lower_bound(GetRandHash());
153     if (it == mapOrphanTransactions.end())
154         it = mapOrphanTransactions.begin();
155     return it->second;
156 }
157
158 BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
159 {
160     CKey key;
161     key.MakeNewKey(true);
162     CBasicKeyStore keystore;
163     keystore.AddKey(key);
164
165     // 50 orphan transactions:
166     for (int i = 0; i < 50; i++)
167     {
168         CMutableTransaction tx;
169         tx.vin.resize(1);
170         tx.vin[0].prevout.n = 0;
171         tx.vin[0].prevout.hash = GetRandHash();
172         tx.vin[0].scriptSig << OP_1;
173         tx.vout.resize(1);
174         tx.vout[0].nValue = 1*CENT;
175         tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID());
176
177         AddOrphanTx(tx);
178     }
179
180     // ... and 50 that depend on other orphans:
181     for (int i = 0; i < 50; i++)
182     {
183         CTransaction txPrev = RandomOrphan();
184
185         CMutableTransaction tx;
186         tx.vin.resize(1);
187         tx.vin[0].prevout.n = 0;
188         tx.vin[0].prevout.hash = txPrev.GetHash();
189         tx.vout.resize(1);
190         tx.vout[0].nValue = 1*CENT;
191         tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID());
192         SignSignature(keystore, txPrev, tx, 0);
193
194         AddOrphanTx(tx);
195     }
196
197     // This really-big orphan should be ignored:
198     for (int i = 0; i < 10; i++)
199     {
200         CTransaction txPrev = RandomOrphan();
201
202         CMutableTransaction tx;
203         tx.vout.resize(1);
204         tx.vout[0].nValue = 1*CENT;
205         tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID());
206         tx.vin.resize(500);
207         for (unsigned int j = 0; j < tx.vin.size(); j++)
208         {
209             tx.vin[j].prevout.n = j;
210             tx.vin[j].prevout.hash = txPrev.GetHash();
211         }
212         SignSignature(keystore, txPrev, tx, 0);
213         // Re-use same signature for other inputs
214         // (they don't have to be valid for this test)
215         for (unsigned int j = 1; j < tx.vin.size(); j++)
216             tx.vin[j].scriptSig = tx.vin[0].scriptSig;
217
218         BOOST_CHECK(!AddOrphanTx(tx));
219     }
220
221     // Test LimitOrphanTxSize() function:
222     LimitOrphanTxSize(40);
223     BOOST_CHECK(mapOrphanTransactions.size() <= 40);
224     LimitOrphanTxSize(10);
225     BOOST_CHECK(mapOrphanTransactions.size() <= 10);
226     LimitOrphanTxSize(0);
227     BOOST_CHECK(mapOrphanTransactions.empty());
228     BOOST_CHECK(mapOrphanTransactionsByPrev.empty());
229 }
230
231 BOOST_AUTO_TEST_SUITE_END()
This page took 0.036437 seconds and 4 git commands to generate.