diff options
Diffstat (limited to 'src/test')
44 files changed, 1017 insertions, 758 deletions
diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index c62e6ae838..4a284517a1 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -18,9 +18,6 @@ #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> // Tests these internal-to-net_processing.cpp methods: @@ -51,7 +48,7 @@ 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); + CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 0, 0, CAddress(), "", true); dummyNode1.SetSendVersion(PROTOCOL_VERSION); GetNodeSignals().InitializeNode(&dummyNode1, *connman); dummyNode1.nVersion = 1; @@ -62,7 +59,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning) 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); + CNode dummyNode2(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr2, 1, 1, CAddress(), "", true); dummyNode2.SetSendVersion(PROTOCOL_VERSION); GetNodeSignals().InitializeNode(&dummyNode2, *connman); dummyNode2.nVersion = 1; @@ -83,7 +80,7 @@ BOOST_AUTO_TEST_CASE(DoS_banscore) connman->ClearBanned(); ForceSetArg("-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); + CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 3, 1, CAddress(), "", true); dummyNode1.SetSendVersion(PROTOCOL_VERSION); GetNodeSignals().InitializeNode(&dummyNode1, *connman); dummyNode1.nVersion = 1; @@ -109,7 +106,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime) 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); + CNode dummyNode(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr, 4, 4, CAddress(), "", true); dummyNode.SetSendVersion(PROTOCOL_VERSION); GetNodeSignals().InitializeNode(&dummyNode, *connman); dummyNode.nVersion = 1; @@ -129,7 +126,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime) CTransactionRef RandomOrphan() { std::map<uint256, COrphanTx>::iterator it; - it = mapOrphanTransactions.lower_bound(GetRandHash()); + it = mapOrphanTransactions.lower_bound(InsecureRand256()); if (it == mapOrphanTransactions.end()) it = mapOrphanTransactions.begin(); return it->second.tx; @@ -148,7 +145,7 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans) CMutableTransaction tx; tx.vin.resize(1); tx.vin[0].prevout.n = 0; - tx.vin[0].prevout.hash = GetRandHash(); + tx.vin[0].prevout.hash = InsecureRand256(); tx.vin[0].scriptSig << OP_1; tx.vout.resize(1); tx.vout[0].nValue = 1*CENT; diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index 39fa381dd0..dc5372a070 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -84,36 +84,47 @@ BOOST_AUTO_TEST_CASE(addrman_simple) CNetAddr source = ResolveIP("252.2.2.2"); - // Test 1: Does Addrman respond correctly when empty. - BOOST_CHECK(addrman.size() == 0); + // Test: Does Addrman respond correctly when empty. + BOOST_CHECK_EQUAL(addrman.size(), 0); CAddrInfo addr_null = addrman.Select(); - BOOST_CHECK(addr_null.ToString() == "[::]:0"); + BOOST_CHECK_EQUAL(addr_null.ToString(), "[::]:0"); - // Test 2: Does Addrman::Add work as expected. + // Test: Does Addrman::Add work as expected. CService addr1 = ResolveService("250.1.1.1", 8333); - addrman.Add(CAddress(addr1, NODE_NONE), source); - BOOST_CHECK(addrman.size() == 1); + BOOST_CHECK(addrman.Add(CAddress(addr1, NODE_NONE), source)); + BOOST_CHECK_EQUAL(addrman.size(), 1); CAddrInfo addr_ret1 = addrman.Select(); - BOOST_CHECK(addr_ret1.ToString() == "250.1.1.1:8333"); + BOOST_CHECK_EQUAL(addr_ret1.ToString(), "250.1.1.1:8333"); - // Test 3: Does IP address deduplication work correctly. + // Test: Does IP address deduplication work correctly. // Expected dup IP should not be added. CService addr1_dup = ResolveService("250.1.1.1", 8333); - addrman.Add(CAddress(addr1_dup, NODE_NONE), source); - BOOST_CHECK(addrman.size() == 1); + BOOST_CHECK(!addrman.Add(CAddress(addr1_dup, NODE_NONE), source)); + BOOST_CHECK_EQUAL(addrman.size(), 1); + + // Test: New table has one addr and we add a diff addr we should + // have at least one addr. + // Note that addrman's size cannot be tested reliably after insertion, as + // hash collisions may occur. But we can always be sure of at least one + // success. - // Test 5: New table has one addr and we add a diff addr we should - // have two addrs. CService addr2 = ResolveService("250.1.1.2", 8333); - addrman.Add(CAddress(addr2, NODE_NONE), source); - BOOST_CHECK(addrman.size() == 2); + BOOST_CHECK(addrman.Add(CAddress(addr2, NODE_NONE), source)); + BOOST_CHECK(addrman.size() >= 1); - // Test 6: AddrMan::Clear() should empty the new table. + // Test: AddrMan::Clear() should empty the new table. addrman.Clear(); - BOOST_CHECK(addrman.size() == 0); + BOOST_CHECK_EQUAL(addrman.size(), 0); CAddrInfo addr_null2 = addrman.Select(); - BOOST_CHECK(addr_null2.ToString() == "[::]:0"); + BOOST_CHECK_EQUAL(addr_null2.ToString(), "[::]:0"); + + // Test: AddrMan::Add multiple addresses works as expected + std::vector<CAddress> vAddr; + vAddr.push_back(CAddress(ResolveService("250.1.1.3", 8333), NODE_NONE)); + vAddr.push_back(CAddress(ResolveService("250.1.1.4", 8333), NODE_NONE)); + BOOST_CHECK(addrman.Add(vAddr, source)); + BOOST_CHECK(addrman.size() >= 1); } BOOST_AUTO_TEST_CASE(addrman_ports) @@ -125,26 +136,26 @@ BOOST_AUTO_TEST_CASE(addrman_ports) CNetAddr source = ResolveIP("252.2.2.2"); - BOOST_CHECK(addrman.size() == 0); + BOOST_CHECK_EQUAL(addrman.size(), 0); // Test 7; Addr with same IP but diff port does not replace existing addr. CService addr1 = ResolveService("250.1.1.1", 8333); addrman.Add(CAddress(addr1, NODE_NONE), source); - BOOST_CHECK(addrman.size() == 1); + BOOST_CHECK_EQUAL(addrman.size(), 1); CService addr1_port = ResolveService("250.1.1.1", 8334); addrman.Add(CAddress(addr1_port, NODE_NONE), source); - BOOST_CHECK(addrman.size() == 1); + BOOST_CHECK_EQUAL(addrman.size(), 1); CAddrInfo addr_ret2 = addrman.Select(); - BOOST_CHECK(addr_ret2.ToString() == "250.1.1.1:8333"); + BOOST_CHECK_EQUAL(addr_ret2.ToString(), "250.1.1.1:8333"); - // Test 8: Add same IP but diff port to tried table, it doesn't get added. + // Test: Add same IP but diff port to tried table, it doesn't get added. // Perhaps this is not ideal behavior but it is the current behavior. addrman.Good(CAddress(addr1_port, NODE_NONE)); - BOOST_CHECK(addrman.size() == 1); + BOOST_CHECK_EQUAL(addrman.size(), 1); bool newOnly = true; CAddrInfo addr_ret3 = addrman.Select(newOnly); - BOOST_CHECK(addr_ret3.ToString() == "250.1.1.1:8333"); + BOOST_CHECK_EQUAL(addr_ret3.ToString(), "250.1.1.1:8333"); } @@ -157,25 +168,25 @@ BOOST_AUTO_TEST_CASE(addrman_select) CNetAddr source = ResolveIP("252.2.2.2"); - // Test 9: Select from new with 1 addr in new. + // Test: Select from new with 1 addr in new. CService addr1 = ResolveService("250.1.1.1", 8333); addrman.Add(CAddress(addr1, NODE_NONE), source); - BOOST_CHECK(addrman.size() == 1); + BOOST_CHECK_EQUAL(addrman.size(), 1); bool newOnly = true; CAddrInfo addr_ret1 = addrman.Select(newOnly); - BOOST_CHECK(addr_ret1.ToString() == "250.1.1.1:8333"); + BOOST_CHECK_EQUAL(addr_ret1.ToString(), "250.1.1.1:8333"); - // Test 10: move addr to tried, select from new expected nothing returned. + // Test: move addr to tried, select from new expected nothing returned. addrman.Good(CAddress(addr1, NODE_NONE)); - BOOST_CHECK(addrman.size() == 1); + BOOST_CHECK_EQUAL(addrman.size(), 1); CAddrInfo addr_ret2 = addrman.Select(newOnly); - BOOST_CHECK(addr_ret2.ToString() == "[::]:0"); + BOOST_CHECK_EQUAL(addr_ret2.ToString(), "[::]:0"); CAddrInfo addr_ret3 = addrman.Select(); - BOOST_CHECK(addr_ret3.ToString() == "250.1.1.1:8333"); + BOOST_CHECK_EQUAL(addr_ret3.ToString(), "250.1.1.1:8333"); - BOOST_CHECK(addrman.size() == 1); + BOOST_CHECK_EQUAL(addrman.size(), 1); // Add three addresses to new table. @@ -199,10 +210,10 @@ BOOST_AUTO_TEST_CASE(addrman_select) addrman.Add(CAddress(addr7, NODE_NONE), ResolveService("250.1.1.3", 8333)); addrman.Good(CAddress(addr7, NODE_NONE)); - // Test 11: 6 addrs + 1 addr from last test = 7. - BOOST_CHECK(addrman.size() == 7); + // Test: 6 addrs + 1 addr from last test = 7. + BOOST_CHECK_EQUAL(addrman.size(), 7); - // Test 12: Select pulls from new and tried regardless of port number. + // Test: Select pulls from new and tried regardless of port number. std::set<uint16_t> ports; for (int i = 0; i < 20; ++i) { ports.insert(addrman.Select().GetPort()); @@ -219,24 +230,24 @@ BOOST_AUTO_TEST_CASE(addrman_new_collisions) CNetAddr source = ResolveIP("252.2.2.2"); - BOOST_CHECK(addrman.size() == 0); + BOOST_CHECK_EQUAL(addrman.size(), 0); for (unsigned int i = 1; i < 18; i++) { CService addr = ResolveService("250.1.1." + boost::to_string(i)); addrman.Add(CAddress(addr, NODE_NONE), source); - //Test 13: No collision in new table yet. - BOOST_CHECK(addrman.size() == i); + //Test: No collision in new table yet. + BOOST_CHECK_EQUAL(addrman.size(), i); } - //Test 14: new table collision! + //Test: new table collision! CService addr1 = ResolveService("250.1.1.18"); addrman.Add(CAddress(addr1, NODE_NONE), source); - BOOST_CHECK(addrman.size() == 17); + BOOST_CHECK_EQUAL(addrman.size(), 17); CService addr2 = ResolveService("250.1.1.19"); addrman.Add(CAddress(addr2, NODE_NONE), source); - BOOST_CHECK(addrman.size() == 18); + BOOST_CHECK_EQUAL(addrman.size(), 18); } BOOST_AUTO_TEST_CASE(addrman_tried_collisions) @@ -248,25 +259,25 @@ BOOST_AUTO_TEST_CASE(addrman_tried_collisions) CNetAddr source = ResolveIP("252.2.2.2"); - BOOST_CHECK(addrman.size() == 0); + BOOST_CHECK_EQUAL(addrman.size(), 0); for (unsigned int i = 1; i < 80; i++) { CService addr = ResolveService("250.1.1." + boost::to_string(i)); addrman.Add(CAddress(addr, NODE_NONE), source); addrman.Good(CAddress(addr, NODE_NONE)); - //Test 15: No collision in tried table yet. + //Test: No collision in tried table yet. BOOST_CHECK_EQUAL(addrman.size(), i); } - //Test 16: tried table collision! + //Test: tried table collision! CService addr1 = ResolveService("250.1.1.80"); addrman.Add(CAddress(addr1, NODE_NONE), source); - BOOST_CHECK(addrman.size() == 79); + BOOST_CHECK_EQUAL(addrman.size(), 79); CService addr2 = ResolveService("250.1.1.81"); addrman.Add(CAddress(addr2, NODE_NONE), source); - BOOST_CHECK(addrman.size() == 80); + BOOST_CHECK_EQUAL(addrman.size(), 80); } BOOST_AUTO_TEST_CASE(addrman_find) @@ -276,7 +287,7 @@ BOOST_AUTO_TEST_CASE(addrman_find) // Set addrman addr placement to be deterministic. addrman.MakeDeterministic(); - BOOST_CHECK(addrman.size() == 0); + BOOST_CHECK_EQUAL(addrman.size(), 0); CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE); CAddress addr2 = CAddress(ResolveService("250.1.2.1", 9999), NODE_NONE); @@ -289,23 +300,20 @@ BOOST_AUTO_TEST_CASE(addrman_find) addrman.Add(addr2, source2); addrman.Add(addr3, source1); - // Test 17: ensure Find returns an IP matching what we searched on. + // Test: ensure Find returns an IP matching what we searched on. CAddrInfo* info1 = addrman.Find(addr1); - BOOST_CHECK(info1); - if (info1) - BOOST_CHECK(info1->ToString() == "250.1.2.1:8333"); + BOOST_REQUIRE(info1); + BOOST_CHECK_EQUAL(info1->ToString(), "250.1.2.1:8333"); // Test 18; Find does not discriminate by port number. CAddrInfo* info2 = addrman.Find(addr2); - BOOST_CHECK(info2); - if (info2 && info1) - BOOST_CHECK(info2->ToString() == info1->ToString()); + BOOST_REQUIRE(info2); + BOOST_CHECK_EQUAL(info2->ToString(), info1->ToString()); - // Test 19: Find returns another IP matching what we searched on. + // Test: Find returns another IP matching what we searched on. CAddrInfo* info3 = addrman.Find(addr3); - BOOST_CHECK(info3); - if (info3) - BOOST_CHECK(info3->ToString() == "251.255.2.1:8333"); + BOOST_REQUIRE(info3); + BOOST_CHECK_EQUAL(info3->ToString(), "251.255.2.1:8333"); } BOOST_AUTO_TEST_CASE(addrman_create) @@ -315,7 +323,7 @@ BOOST_AUTO_TEST_CASE(addrman_create) // Set addrman addr placement to be deterministic. addrman.MakeDeterministic(); - BOOST_CHECK(addrman.size() == 0); + BOOST_CHECK_EQUAL(addrman.size(), 0); CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE); CNetAddr source1 = ResolveIP("250.1.2.1"); @@ -323,11 +331,11 @@ BOOST_AUTO_TEST_CASE(addrman_create) int nId; CAddrInfo* pinfo = addrman.Create(addr1, source1, &nId); - // Test 20: The result should be the same as the input addr. - BOOST_CHECK(pinfo->ToString() == "250.1.2.1:8333"); + // Test: The result should be the same as the input addr. + BOOST_CHECK_EQUAL(pinfo->ToString(), "250.1.2.1:8333"); CAddrInfo* info2 = addrman.Find(addr1); - BOOST_CHECK(info2->ToString() == "250.1.2.1:8333"); + BOOST_CHECK_EQUAL(info2->ToString(), "250.1.2.1:8333"); } @@ -338,7 +346,7 @@ BOOST_AUTO_TEST_CASE(addrman_delete) // Set addrman addr placement to be deterministic. addrman.MakeDeterministic(); - BOOST_CHECK(addrman.size() == 0); + BOOST_CHECK_EQUAL(addrman.size(), 0); CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE); CNetAddr source1 = ResolveIP("250.1.2.1"); @@ -346,10 +354,10 @@ BOOST_AUTO_TEST_CASE(addrman_delete) int nId; addrman.Create(addr1, source1, &nId); - // Test 21: Delete should actually delete the addr. - BOOST_CHECK(addrman.size() == 1); + // Test: Delete should actually delete the addr. + BOOST_CHECK_EQUAL(addrman.size(), 1); addrman.Delete(nId); - BOOST_CHECK(addrman.size() == 0); + BOOST_CHECK_EQUAL(addrman.size(), 0); CAddrInfo* info2 = addrman.Find(addr1); BOOST_CHECK(info2 == NULL); } @@ -361,11 +369,11 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) // Set addrman addr placement to be deterministic. addrman.MakeDeterministic(); - // Test 22: Sanity check, GetAddr should never return anything if addrman + // Test: Sanity check, GetAddr should never return anything if addrman // is empty. - BOOST_CHECK(addrman.size() == 0); + BOOST_CHECK_EQUAL(addrman.size(), 0); std::vector<CAddress> vAddr1 = addrman.GetAddr(); - BOOST_CHECK(vAddr1.size() == 0); + BOOST_CHECK_EQUAL(vAddr1.size(), 0); CAddress addr1 = CAddress(ResolveService("250.250.2.1", 8333), NODE_NONE); addr1.nTime = GetAdjustedTime(); // Set time so isTerrible = false @@ -380,7 +388,7 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) CNetAddr source1 = ResolveIP("250.1.2.1"); CNetAddr source2 = ResolveIP("250.2.3.3"); - // Test 23: Ensure GetAddr works with new addresses. + // Test: Ensure GetAddr works with new addresses. addrman.Add(addr1, source1); addrman.Add(addr2, source2); addrman.Add(addr3, source1); @@ -388,21 +396,20 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) addrman.Add(addr5, source1); // GetAddr returns 23% of addresses, 23% of 5 is 1 rounded down. - BOOST_CHECK(addrman.GetAddr().size() == 1); + BOOST_CHECK_EQUAL(addrman.GetAddr().size(), 1); - // Test 24: Ensure GetAddr works with new and tried addresses. + // Test: Ensure GetAddr works with new and tried addresses. addrman.Good(CAddress(addr1, NODE_NONE)); addrman.Good(CAddress(addr2, NODE_NONE)); - BOOST_CHECK(addrman.GetAddr().size() == 1); + BOOST_CHECK_EQUAL(addrman.GetAddr().size(), 1); - // Test 25: Ensure GetAddr still returns 23% when addrman has many addrs. + // Test: Ensure GetAddr still returns 23% when addrman has many addrs. for (unsigned int i = 1; i < (8 * 256); i++) { int octet1 = i % 256; - int octet2 = (i / 256) % 256; - int octet3 = (i / (256 * 2)) % 256; - std::string strAddr = boost::to_string(octet1) + "." + boost::to_string(octet2) + "." + boost::to_string(octet3) + ".23"; + int octet2 = i >> 8 % 256; + std::string strAddr = boost::to_string(octet1) + "." + boost::to_string(octet2) + ".1.23"; CAddress addr = CAddress(ResolveService(strAddr), NODE_NONE); - + // Ensure that for all addrs in addrman, isTerrible == false. addr.nTime = GetAdjustedTime(); addrman.Add(addr, ResolveIP(strAddr)); @@ -412,10 +419,10 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) std::vector<CAddress> vAddr = addrman.GetAddr(); size_t percent23 = (addrman.size() * 23) / 100; - BOOST_CHECK(vAddr.size() == percent23); - BOOST_CHECK(vAddr.size() == 461); + BOOST_CHECK_EQUAL(vAddr.size(), percent23); + BOOST_CHECK_EQUAL(vAddr.size(), 461); // (Addrman.size() < number of addresses added) due to address collisions. - BOOST_CHECK(addrman.size() == 2007); + BOOST_CHECK_EQUAL(addrman.size(), 2006); } @@ -438,13 +445,13 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket) uint256 nKey2 = (uint256)(CHashWriter(SER_GETHASH, 0) << 2).GetHash(); - BOOST_CHECK(info1.GetTriedBucket(nKey1) == 40); + BOOST_CHECK_EQUAL(info1.GetTriedBucket(nKey1), 40); - // Test 26: Make sure key actually randomizes bucket placement. A fail on + // Test: Make sure key actually randomizes bucket placement. A fail on // this test could be a security issue. BOOST_CHECK(info1.GetTriedBucket(nKey1) != info1.GetTriedBucket(nKey2)); - // Test 27: Two addresses with same IP but different ports can map to + // Test: Two addresses with same IP but different ports can map to // different buckets because they have different keys. CAddrInfo info2 = CAddrInfo(addr2, source1); @@ -459,9 +466,9 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket) int bucket = infoi.GetTriedBucket(nKey1); buckets.insert(bucket); } - // Test 28: IP addresses in the same group (\16 prefix for IPv4) should + // Test: IP addresses in the same group (\16 prefix for IPv4) should // never get more than 8 buckets - BOOST_CHECK(buckets.size() == 8); + BOOST_CHECK_EQUAL(buckets.size(), 8); buckets.clear(); for (int j = 0; j < 255; j++) { @@ -471,9 +478,9 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket) int bucket = infoj.GetTriedBucket(nKey1); buckets.insert(bucket); } - // Test 29: IP addresses in the different groups should map to more than + // Test: IP addresses in the different groups should map to more than // 8 buckets. - BOOST_CHECK(buckets.size() == 160); + BOOST_CHECK_EQUAL(buckets.size(), 160); } BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) @@ -493,16 +500,18 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) uint256 nKey1 = (uint256)(CHashWriter(SER_GETHASH, 0) << 1).GetHash(); uint256 nKey2 = (uint256)(CHashWriter(SER_GETHASH, 0) << 2).GetHash(); - BOOST_CHECK(info1.GetNewBucket(nKey1) == 786); + // Test: Make sure the buckets are what we expect + BOOST_CHECK_EQUAL(info1.GetNewBucket(nKey1), 786); + BOOST_CHECK_EQUAL(info1.GetNewBucket(nKey1, source1), 786); - // Test 30: Make sure key actually randomizes bucket placement. A fail on + // Test: Make sure key actually randomizes bucket placement. A fail on // this test could be a security issue. BOOST_CHECK(info1.GetNewBucket(nKey1) != info1.GetNewBucket(nKey2)); - // Test 31: Ports should not effect bucket placement in the addr + // Test: Ports should not effect bucket placement in the addr CAddrInfo info2 = CAddrInfo(addr2, source1); BOOST_CHECK(info1.GetKey() != info2.GetKey()); - BOOST_CHECK(info1.GetNewBucket(nKey1) == info2.GetNewBucket(nKey1)); + BOOST_CHECK_EQUAL(info1.GetNewBucket(nKey1), info2.GetNewBucket(nKey1)); std::set<int> buckets; for (int i = 0; i < 255; i++) { @@ -512,9 +521,9 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) int bucket = infoi.GetNewBucket(nKey1); buckets.insert(bucket); } - // Test 32: IP addresses in the same group (\16 prefix for IPv4) should + // Test: IP addresses in the same group (\16 prefix for IPv4) should // always map to the same bucket. - BOOST_CHECK(buckets.size() == 1); + BOOST_CHECK_EQUAL(buckets.size(), 1); buckets.clear(); for (int j = 0; j < 4 * 255; j++) { @@ -525,7 +534,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) int bucket = infoj.GetNewBucket(nKey1); buckets.insert(bucket); } - // Test 33: IP addresses in the same source groups should map to no more + // Test: IP addresses in the same source groups should map to no more // than 64 buckets. BOOST_CHECK(buckets.size() <= 64); @@ -537,7 +546,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) int bucket = infoj.GetNewBucket(nKey1); buckets.insert(bucket); } - // Test 34: IP addresses in the different source groups should map to more + // Test: IP addresses in the different source groups should map to more // than 64 buckets. BOOST_CHECK(buckets.size() > 64); } diff --git a/src/test/amount_tests.cpp b/src/test/amount_tests.cpp index c95def5e87..952cf901f0 100644 --- a/src/test/amount_tests.cpp +++ b/src/test/amount_tests.cpp @@ -3,6 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "amount.h" +#include "policy/feerate.h" #include "test/test_bitcoin.h" #include <boost/test/unit_test.hpp> diff --git a/src/test/arith_uint256_tests.cpp b/src/test/arith_uint256_tests.cpp index 45ae7d4636..2c98fbcfd6 100644 --- a/src/test/arith_uint256_tests.cpp +++ b/src/test/arith_uint256_tests.cpp @@ -219,7 +219,7 @@ BOOST_AUTO_TEST_CASE( unaryOperators ) // ! ~ - // Check if doing _A_ _OP_ _B_ results in the same as applying _OP_ onto each -// element of Aarray and Barray, and then converting the result into a arith_uint256. +// element of Aarray and Barray, and then converting the result into an arith_uint256. #define CHECKBITWISEOPERATOR(_A_,_B_,_OP_) \ for (unsigned int i = 0; i < 32; ++i) { TmpArray[i] = _A_##Array[i] _OP_ _B_##Array[i]; } \ BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (_A_##L _OP_ _B_##L)); diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp index 6cd998990b..b33cdb9fe6 100644 --- a/src/test/base58_tests.cpp +++ b/src/test/base58_tests.cpp @@ -15,7 +15,6 @@ #include "utilstrencodings.h" #include "test/test_bitcoin.h" -#include <boost/foreach.hpp> #include <boost/test/unit_test.hpp> #include <univalue.h> diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp index c148ad6d82..6bcd550d7b 100644 --- a/src/test/bip32_tests.cpp +++ b/src/test/bip32_tests.cpp @@ -93,7 +93,7 @@ void RunTest(const TestVector &test) { CExtPubKey pubkey; key.SetMaster(&seed[0], seed.size()); pubkey = key.Neuter(); - BOOST_FOREACH(const TestDerivation &derive, test.vDerive) { + for (const TestDerivation &derive : test.vDerive) { unsigned char data[74]; key.Encode(data); pubkey.Encode(data); diff --git a/src/test/blockencodings_tests.cpp b/src/test/blockencodings_tests.cpp index 9e4a56919d..10a40fea3c 100644 --- a/src/test/blockencodings_tests.cpp +++ b/src/test/blockencodings_tests.cpp @@ -30,16 +30,16 @@ static CBlock BuildBlockTestCase() { block.vtx.resize(3); block.vtx[0] = MakeTransactionRef(tx); block.nVersion = 42; - block.hashPrevBlock = GetRandHash(); + block.hashPrevBlock = InsecureRand256(); block.nBits = 0x207fffff; - tx.vin[0].prevout.hash = GetRandHash(); + tx.vin[0].prevout.hash = InsecureRand256(); tx.vin[0].prevout.n = 0; block.vtx[1] = MakeTransactionRef(tx); tx.vin.resize(10); for (size_t i = 0; i < tx.vin.size(); i++) { - tx.vin[i].prevout.hash = GetRandHash(); + tx.vin[i].prevout.hash = InsecureRand256(); tx.vin[i].prevout.n = 0; } block.vtx[2] = MakeTransactionRef(tx); @@ -283,7 +283,7 @@ BOOST_AUTO_TEST_CASE(EmptyBlockRoundTripTest) block.vtx.resize(1); block.vtx[0] = MakeTransactionRef(std::move(coinbase)); block.nVersion = 42; - block.hashPrevBlock = GetRandHash(); + block.hashPrevBlock = InsecureRand256(); block.nBits = 0x207fffff; bool mutated; @@ -316,7 +316,7 @@ BOOST_AUTO_TEST_CASE(EmptyBlockRoundTripTest) BOOST_AUTO_TEST_CASE(TransactionsRequestSerializationTest) { BlockTransactionsRequest req1; - req1.blockhash = GetRandHash(); + req1.blockhash = InsecureRand256(); req1.indexes.resize(4); req1.indexes[0] = 0; req1.indexes[1] = 1; diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp index 27bc92d670..2085b5cb2b 100644 --- a/src/test/bloom_tests.cpp +++ b/src/test/bloom_tests.cpp @@ -19,7 +19,6 @@ #include <vector> #include <boost/test/unit_test.hpp> -#include <boost/tuple/tuple.hpp> BOOST_FIXTURE_TEST_SUITE(bloom_tests, BasicTestingSetup) @@ -463,7 +462,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_4_test_update_none) static std::vector<unsigned char> RandomData() { - uint256 r = GetRandHash(); + uint256 r = InsecureRand256(); return std::vector<unsigned char>(r.begin(), r.end()); } diff --git a/src/test/checkqueue_tests.cpp b/src/test/checkqueue_tests.cpp index 287395c6c6..6ae0bcadd0 100644 --- a/src/test/checkqueue_tests.cpp +++ b/src/test/checkqueue_tests.cpp @@ -160,7 +160,7 @@ void Correct_Queue_range(std::vector<size_t> range) FakeCheckCheckCompletion::n_calls = 0; CCheckQueueControl<FakeCheckCheckCompletion> control(small_queue.get()); while (total) { - vChecks.resize(std::min(total, (size_t) GetRand(10))); + vChecks.resize(std::min(total, (size_t) InsecureRandRange(10))); total -= vChecks.size(); control.Add(vChecks); } @@ -204,7 +204,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_Correct_Random) { std::vector<size_t> range; range.reserve(100000/1000); - for (size_t i = 2; i < 100000; i += std::max((size_t)1, (size_t)GetRand(std::min((size_t)1000, ((size_t)100000) - i)))) + for (size_t i = 2; i < 100000; i += std::max((size_t)1, (size_t)InsecureRandRange(std::min((size_t)1000, ((size_t)100000) - i)))) range.push_back(i); Correct_Queue_range(range); } @@ -224,7 +224,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_Catches_Failure) CCheckQueueControl<FailingCheck> control(fail_queue.get()); size_t remaining = i; while (remaining) { - size_t r = GetRand(10); + size_t r = InsecureRandRange(10); std::vector<FailingCheck> vChecks; vChecks.reserve(r); @@ -286,7 +286,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_UniqueCheck) { CCheckQueueControl<UniqueCheck> control(queue.get()); while (total) { - size_t r = GetRand(10); + size_t r = InsecureRandRange(10); std::vector<UniqueCheck> vChecks; for (size_t k = 0; k < r && total; k++) vChecks.emplace_back(--total); @@ -320,7 +320,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_Memory) { CCheckQueueControl<MemoryCheck> control(queue.get()); while (total) { - size_t r = GetRand(10); + size_t r = InsecureRandRange(10); std::vector<MemoryCheck> vChecks; for (size_t k = 0; k < r && total; k++) { total--; @@ -402,12 +402,12 @@ BOOST_AUTO_TEST_CASE(test_CheckQueueControl_Locks) { boost::thread_group tg; std::mutex m; - bool has_lock {false}; - bool has_tried {false}; - bool done {false}; - bool done_ack {false}; std::condition_variable cv; { + bool has_lock {false}; + bool has_tried {false}; + bool done {false}; + bool done_ack {false}; std::unique_lock<std::mutex> l(m); tg.create_thread([&]{ CCheckQueueControl<FakeCheck> control(queue.get()); diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index 850b983c45..622b157621 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -8,7 +8,6 @@ #include "undo.h" #include "utilstrencodings.h" #include "test/test_bitcoin.h" -#include "test/test_random.h" #include "validation.h" #include "consensus/validation.h" @@ -17,46 +16,55 @@ #include <boost/test/unit_test.hpp> -bool ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, const COutPoint& out); +int ApplyTxInUndo(Coin&& undo, CCoinsViewCache& view, const COutPoint& out); void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo &txundo, int nHeight); namespace { +//! equality test +bool operator==(const Coin &a, const Coin &b) { + // Empty Coin objects are always equal. + if (a.IsSpent() && b.IsSpent()) return true; + return a.fCoinBase == b.fCoinBase && + a.nHeight == b.nHeight && + a.out == b.out; +} + class CCoinsViewTest : public CCoinsView { uint256 hashBestBlock_; - std::map<uint256, CCoins> map_; + std::map<COutPoint, Coin> map_; public: - bool GetCoins(const uint256& txid, CCoins& coins) const + bool GetCoin(const COutPoint& outpoint, Coin& coin) const override { - std::map<uint256, CCoins>::const_iterator it = map_.find(txid); + std::map<COutPoint, Coin>::const_iterator it = map_.find(outpoint); if (it == map_.end()) { return false; } - coins = it->second; - if (coins.IsPruned() && insecure_rand() % 2 == 0) { + coin = it->second; + if (coin.IsSpent() && InsecureRandBool() == 0) { // Randomly return false in case of an empty entry. return false; } return true; } - bool HaveCoins(const uint256& txid) const + bool HaveCoin(const COutPoint& outpoint) const override { - CCoins coins; - return GetCoins(txid, coins); + Coin coin; + return GetCoin(outpoint, coin); } - uint256 GetBestBlock() const { return hashBestBlock_; } + uint256 GetBestBlock() const override { return hashBestBlock_; } - bool BatchWrite(CCoinsMap& mapCoins, const uint256& hashBlock) + bool BatchWrite(CCoinsMap& mapCoins, const uint256& hashBlock) override { for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end(); ) { if (it->second.flags & CCoinsCacheEntry::DIRTY) { // Same optimization used in CCoinsViewDB is to only write dirty entries. - map_[it->first] = it->second.coins; - if (it->second.coins.IsPruned() && insecure_rand() % 3 == 0) { + map_[it->first] = it->second.coin; + if (it->second.coin.IsSpent() && InsecureRandRange(3) == 0) { // Randomly delete empty entries on write. map_.erase(it->first); } @@ -78,9 +86,12 @@ public: { // Manually recompute the dynamic usage of the whole data, and compare it. size_t ret = memusage::DynamicUsage(cacheCoins); + size_t count = 0; for (CCoinsMap::iterator it = cacheCoins.begin(); it != cacheCoins.end(); it++) { - ret += it->second.coins.DynamicMemoryUsage(); + ret += it->second.coin.DynamicMemoryUsage(); + ++count; } + BOOST_CHECK_EQUAL(GetCacheSize(), count); BOOST_CHECK_EQUAL(DynamicMemoryUsage(), ret); } @@ -97,7 +108,7 @@ static const unsigned int NUM_SIMULATION_ITERATIONS = 40000; // This is a large randomized insert/remove simulation test on a variable-size // stack of caches on top of CCoinsViewTest. // -// It will randomly create/update/delete CCoins entries to a tip of caches, with +// It will randomly create/update/delete Coin entries to a tip of caches, with // txids picked from a limited list of random 256-bit hashes. Occasionally, a // new tip is added to the stack of caches, or the tip is flushed and removed. // @@ -109,13 +120,15 @@ BOOST_AUTO_TEST_CASE(coins_cache_simulation_test) bool removed_all_caches = false; bool reached_4_caches = false; bool added_an_entry = false; + bool added_an_unspendable_entry = false; bool removed_an_entry = false; bool updated_an_entry = false; bool found_an_entry = false; bool missed_an_entry = false; + bool uncached_an_entry = false; // A simple map to track what we expect the cache stack to represent. - std::map<uint256, CCoins> result; + std::map<COutPoint, Coin> result; // The cache stack. CCoinsViewTest base; // A CCoinsViewTest at the bottom. @@ -126,66 +139,81 @@ BOOST_AUTO_TEST_CASE(coins_cache_simulation_test) std::vector<uint256> txids; txids.resize(NUM_SIMULATION_ITERATIONS / 8); for (unsigned int i = 0; i < txids.size(); i++) { - txids[i] = GetRandHash(); + txids[i] = InsecureRand256(); } for (unsigned int i = 0; i < NUM_SIMULATION_ITERATIONS; i++) { // Do a random modification. { - uint256 txid = txids[insecure_rand() % txids.size()]; // txid we're going to modify in this iteration. - CCoins& coins = result[txid]; - CCoinsModifier entry = stack.back()->ModifyCoins(txid); - BOOST_CHECK(coins == *entry); - if (insecure_rand() % 5 == 0 || coins.IsPruned()) { - if (coins.IsPruned()) { - added_an_entry = true; + uint256 txid = txids[InsecureRandRange(txids.size())]; // txid we're going to modify in this iteration. + Coin& coin = result[COutPoint(txid, 0)]; + const Coin& entry = (InsecureRandRange(500) == 0) ? AccessByTxid(*stack.back(), txid) : stack.back()->AccessCoin(COutPoint(txid, 0)); + BOOST_CHECK(coin == entry); + + if (InsecureRandRange(5) == 0 || coin.IsSpent()) { + Coin newcoin; + newcoin.out.nValue = InsecureRand32(); + newcoin.nHeight = 1; + if (InsecureRandRange(16) == 0 && coin.IsSpent()) { + newcoin.out.scriptPubKey.assign(1 + InsecureRandBits(6), OP_RETURN); + BOOST_CHECK(newcoin.out.scriptPubKey.IsUnspendable()); + added_an_unspendable_entry = true; } else { - updated_an_entry = true; + newcoin.out.scriptPubKey.assign(InsecureRandBits(6), 0); // Random sizes so we can test memory usage accounting + (coin.IsSpent() ? added_an_entry : updated_an_entry) = true; + coin = newcoin; } - coins.nVersion = insecure_rand(); - coins.vout.resize(1); - coins.vout[0].nValue = insecure_rand(); - *entry = coins; + stack.back()->AddCoin(COutPoint(txid, 0), std::move(newcoin), !coin.IsSpent() || InsecureRand32() & 1); } else { - coins.Clear(); - entry->Clear(); removed_an_entry = true; + coin.Clear(); + stack.back()->SpendCoin(COutPoint(txid, 0)); } } + // One every 10 iterations, remove a random entry from the cache + if (InsecureRandRange(10) == 0) { + COutPoint out(txids[InsecureRand32() % txids.size()], 0); + int cacheid = InsecureRand32() % stack.size(); + stack[cacheid]->Uncache(out); + uncached_an_entry |= !stack[cacheid]->HaveCoinInCache(out); + } + // Once every 1000 iterations and at the end, verify the full cache. - if (insecure_rand() % 1000 == 1 || i == NUM_SIMULATION_ITERATIONS - 1) { - for (std::map<uint256, CCoins>::iterator it = result.begin(); it != result.end(); it++) { - const CCoins* coins = stack.back()->AccessCoins(it->first); - if (coins) { - BOOST_CHECK(*coins == it->second); - found_an_entry = true; - } else { - BOOST_CHECK(it->second.IsPruned()); + if (InsecureRandRange(1000) == 1 || i == NUM_SIMULATION_ITERATIONS - 1) { + for (auto it = result.begin(); it != result.end(); it++) { + bool have = stack.back()->HaveCoin(it->first); + const Coin& coin = stack.back()->AccessCoin(it->first); + BOOST_CHECK(have == !coin.IsSpent()); + BOOST_CHECK(coin == it->second); + if (coin.IsSpent()) { missed_an_entry = true; + } else { + BOOST_CHECK(stack.back()->HaveCoinInCache(it->first)); + found_an_entry = true; } } - BOOST_FOREACH(const CCoinsViewCacheTest *test, stack) { + for (const CCoinsViewCacheTest *test : stack) { test->SelfTest(); } } - if (insecure_rand() % 100 == 0) { + if (InsecureRandRange(100) == 0) { // Every 100 iterations, flush an intermediate cache - if (stack.size() > 1 && insecure_rand() % 2 == 0) { - unsigned int flushIndex = insecure_rand() % (stack.size() - 1); + if (stack.size() > 1 && InsecureRandBool() == 0) { + unsigned int flushIndex = InsecureRandRange(stack.size() - 1); stack[flushIndex]->Flush(); } } - if (insecure_rand() % 100 == 0) { + if (InsecureRandRange(100) == 0) { // Every 100 iterations, change the cache stack. - if (stack.size() > 0 && insecure_rand() % 2 == 0) { + if (stack.size() > 0 && InsecureRandBool() == 0) { //Remove the top cache stack.back()->Flush(); delete stack.back(); stack.pop_back(); } - if (stack.size() == 0 || (stack.size() < 4 && insecure_rand() % 2)) { + if (stack.size() == 0 || (stack.size() < 4 && InsecureRandBool())) { //Add a new cache CCoinsView* tip = &base; if (stack.size() > 0) { @@ -211,25 +239,27 @@ BOOST_AUTO_TEST_CASE(coins_cache_simulation_test) BOOST_CHECK(removed_all_caches); BOOST_CHECK(reached_4_caches); BOOST_CHECK(added_an_entry); + BOOST_CHECK(added_an_unspendable_entry); BOOST_CHECK(removed_an_entry); BOOST_CHECK(updated_an_entry); BOOST_CHECK(found_an_entry); BOOST_CHECK(missed_an_entry); + BOOST_CHECK(uncached_an_entry); } -typedef std::tuple<CTransaction,CTxUndo,CCoins> TxData; // Store of all necessary tx and undo data for next test -std::map<uint256, TxData> alltxs; - -TxData &FindRandomFrom(const std::set<uint256> &txidset) { - assert(txidset.size()); - std::set<uint256>::iterator txIt = txidset.lower_bound(GetRandHash()); - if (txIt == txidset.end()) { - txIt = txidset.begin(); +typedef std::map<COutPoint, std::tuple<CTransaction,CTxUndo,Coin>> UtxoData; +UtxoData utxoData; + +UtxoData::iterator FindRandomFrom(const std::set<COutPoint> &utxoSet) { + assert(utxoSet.size()); + auto utxoSetIt = utxoSet.lower_bound(COutPoint(InsecureRand256(), 0)); + if (utxoSetIt == utxoSet.end()) { + utxoSetIt = utxoSet.begin(); } - std::map<uint256, TxData>::iterator txdit = alltxs.find(*txIt); - assert(txdit != alltxs.end()); - return txdit->second; + auto utxoDataIt = utxoData.find(*utxoSetIt); + assert(utxoDataIt != utxoData.end()); + return utxoDataIt; } @@ -242,7 +272,7 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test) { bool spent_a_duplicate_coinbase = false; // A simple map to track what we expect the cache stack to represent. - std::map<uint256, CCoins> result; + std::map<COutPoint, Coin> result; // The cache stack. CCoinsViewTest base; // A CCoinsViewTest at the bottom. @@ -250,13 +280,13 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test) stack.push_back(new CCoinsViewCacheTest(&base)); // Start with one cache. // Track the txids we've used in various sets - std::set<uint256> coinbaseids; - std::set<uint256> disconnectedids; - std::set<uint256> duplicateids; - std::set<uint256> utxoset; + std::set<COutPoint> coinbase_coins; + std::set<COutPoint> disconnected_coins; + std::set<COutPoint> duplicate_coins; + std::set<COutPoint> utxoset; for (unsigned int i = 0; i < NUM_SIMULATION_ITERATIONS; i++) { - uint32_t randiter = insecure_rand(); + uint32_t randiter = InsecureRand32(); // 19/20 txs add a new transaction if (randiter % 20 < 19) { @@ -264,23 +294,24 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test) tx.vin.resize(1); tx.vout.resize(1); tx.vout[0].nValue = i; //Keep txs unique unless intended to duplicate - unsigned int height = insecure_rand(); - CCoins oldcoins; + tx.vout[0].scriptPubKey.assign(InsecureRand32() & 0x3F, 0); // Random sizes so we can test memory usage accounting + unsigned int height = InsecureRand32(); + Coin old_coin; // 2/20 times create a new coinbase - if (randiter % 20 < 2 || coinbaseids.size() < 10) { + if (randiter % 20 < 2 || coinbase_coins.size() < 10) { // 1/10 of those times create a duplicate coinbase - if (insecure_rand() % 10 == 0 && coinbaseids.size()) { - TxData &txd = FindRandomFrom(coinbaseids); + if (InsecureRandRange(10) == 0 && coinbase_coins.size()) { + auto utxod = FindRandomFrom(coinbase_coins); // Reuse the exact same coinbase - tx = std::get<0>(txd); + tx = std::get<0>(utxod->second); // shouldn't be available for reconnection if its been duplicated - disconnectedids.erase(tx.GetHash()); + disconnected_coins.erase(utxod->first); - duplicateids.insert(tx.GetHash()); + duplicate_coins.insert(utxod->first); } else { - coinbaseids.insert(tx.GetHash()); + coinbase_coins.insert(COutPoint(tx.GetHash(), 0)); } assert(CTransaction(tx).IsCoinBase()); } @@ -288,129 +319,133 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test) // 17/20 times reconnect previous or add a regular tx else { - uint256 prevouthash; + COutPoint prevout; // 1/20 times reconnect a previously disconnected tx - if (randiter % 20 == 2 && disconnectedids.size()) { - TxData &txd = FindRandomFrom(disconnectedids); - tx = std::get<0>(txd); - prevouthash = tx.vin[0].prevout.hash; - if (!CTransaction(tx).IsCoinBase() && !utxoset.count(prevouthash)) { - disconnectedids.erase(tx.GetHash()); + if (randiter % 20 == 2 && disconnected_coins.size()) { + auto utxod = FindRandomFrom(disconnected_coins); + tx = std::get<0>(utxod->second); + prevout = tx.vin[0].prevout; + if (!CTransaction(tx).IsCoinBase() && !utxoset.count(prevout)) { + disconnected_coins.erase(utxod->first); continue; } // If this tx is already IN the UTXO, then it must be a coinbase, and it must be a duplicate - if (utxoset.count(tx.GetHash())) { + if (utxoset.count(utxod->first)) { assert(CTransaction(tx).IsCoinBase()); - assert(duplicateids.count(tx.GetHash())); + assert(duplicate_coins.count(utxod->first)); } - disconnectedids.erase(tx.GetHash()); + disconnected_coins.erase(utxod->first); } // 16/20 times create a regular tx else { - TxData &txd = FindRandomFrom(utxoset); - prevouthash = std::get<0>(txd).GetHash(); + auto utxod = FindRandomFrom(utxoset); + prevout = utxod->first; // Construct the tx to spend the coins of prevouthash - tx.vin[0].prevout.hash = prevouthash; - tx.vin[0].prevout.n = 0; + tx.vin[0].prevout = prevout; assert(!CTransaction(tx).IsCoinBase()); } // In this simple test coins only have two states, spent or unspent, save the unspent state to restore - oldcoins = result[prevouthash]; + old_coin = result[prevout]; // Update the expected result of prevouthash to know these coins are spent - result[prevouthash].Clear(); + result[prevout].Clear(); - utxoset.erase(prevouthash); + utxoset.erase(prevout); // The test is designed to ensure spending a duplicate coinbase will work properly // if that ever happens and not resurrect the previously overwritten coinbase - if (duplicateids.count(prevouthash)) + if (duplicate_coins.count(prevout)) { spent_a_duplicate_coinbase = true; + } } // Update the expected result to know about the new output coins - result[tx.GetHash()].FromTx(tx, height); + assert(tx.vout.size() == 1); + const COutPoint outpoint(tx.GetHash(), 0); + result[outpoint] = Coin(tx.vout[0], height, CTransaction(tx).IsCoinBase()); // Call UpdateCoins on the top cache CTxUndo undo; UpdateCoins(tx, *(stack.back()), undo, height); // Update the utxo set for future spends - utxoset.insert(tx.GetHash()); + utxoset.insert(outpoint); // Track this tx and undo info to use later - alltxs.insert(std::make_pair(tx.GetHash(),std::make_tuple(tx,undo,oldcoins))); - } - - //1/20 times undo a previous transaction - else if (utxoset.size()) { - TxData &txd = FindRandomFrom(utxoset); + utxoData.emplace(outpoint, std::make_tuple(tx,undo,old_coin)); + } else if (utxoset.size()) { + //1/20 times undo a previous transaction + auto utxod = FindRandomFrom(utxoset); - CTransaction &tx = std::get<0>(txd); - CTxUndo &undo = std::get<1>(txd); - CCoins &origcoins = std::get<2>(txd); - - uint256 undohash = tx.GetHash(); + CTransaction &tx = std::get<0>(utxod->second); + CTxUndo &undo = std::get<1>(utxod->second); + Coin &orig_coin = std::get<2>(utxod->second); // Update the expected result // Remove new outputs - result[undohash].Clear(); + result[utxod->first].Clear(); // If not coinbase restore prevout if (!tx.IsCoinBase()) { - result[tx.vin[0].prevout.hash] = origcoins; + result[tx.vin[0].prevout] = orig_coin; } // Disconnect the tx from the current UTXO // See code in DisconnectBlock // remove outputs - { - CCoinsModifier outs = stack.back()->ModifyCoins(undohash); - outs->Clear(); - } + stack.back()->SpendCoin(utxod->first); // restore inputs if (!tx.IsCoinBase()) { const COutPoint &out = tx.vin[0].prevout; - const CTxInUndo &undoin = undo.vprevout[0]; - ApplyTxInUndo(undoin, *(stack.back()), out); + Coin coin = undo.vprevout[0]; + ApplyTxInUndo(std::move(coin), *(stack.back()), out); } // Store as a candidate for reconnection - disconnectedids.insert(undohash); + disconnected_coins.insert(utxod->first); // Update the utxoset - utxoset.erase(undohash); + utxoset.erase(utxod->first); if (!tx.IsCoinBase()) - utxoset.insert(tx.vin[0].prevout.hash); + utxoset.insert(tx.vin[0].prevout); } // Once every 1000 iterations and at the end, verify the full cache. - if (insecure_rand() % 1000 == 1 || i == NUM_SIMULATION_ITERATIONS - 1) { - for (std::map<uint256, CCoins>::iterator it = result.begin(); it != result.end(); it++) { - const CCoins* coins = stack.back()->AccessCoins(it->first); - if (coins) { - BOOST_CHECK(*coins == it->second); - } else { - BOOST_CHECK(it->second.IsPruned()); - } + if (InsecureRandRange(1000) == 1 || i == NUM_SIMULATION_ITERATIONS - 1) { + for (auto it = result.begin(); it != result.end(); it++) { + bool have = stack.back()->HaveCoin(it->first); + const Coin& coin = stack.back()->AccessCoin(it->first); + BOOST_CHECK(have == !coin.IsSpent()); + BOOST_CHECK(coin == it->second); } } - if (insecure_rand() % 100 == 0) { + // One every 10 iterations, remove a random entry from the cache + if (utxoset.size() > 1 && InsecureRandRange(30) == 0) { + stack[InsecureRand32() % stack.size()]->Uncache(FindRandomFrom(utxoset)->first); + } + if (disconnected_coins.size() > 1 && InsecureRandRange(30) == 0) { + stack[InsecureRand32() % stack.size()]->Uncache(FindRandomFrom(disconnected_coins)->first); + } + if (duplicate_coins.size() > 1 && InsecureRandRange(30) == 0) { + stack[InsecureRand32() % stack.size()]->Uncache(FindRandomFrom(duplicate_coins)->first); + } + + if (InsecureRandRange(100) == 0) { // Every 100 iterations, flush an intermediate cache - if (stack.size() > 1 && insecure_rand() % 2 == 0) { - unsigned int flushIndex = insecure_rand() % (stack.size() - 1); + if (stack.size() > 1 && InsecureRandBool() == 0) { + unsigned int flushIndex = InsecureRandRange(stack.size() - 1); stack[flushIndex]->Flush(); } } - if (insecure_rand() % 100 == 0) { + if (InsecureRandRange(100) == 0) { // Every 100 iterations, change the cache stack. - if (stack.size() > 0 && insecure_rand() % 2 == 0) { + if (stack.size() > 0 && InsecureRandBool() == 0) { stack.back()->Flush(); delete stack.back(); stack.pop_back(); } - if (stack.size() == 0 || (stack.size() < 4 && insecure_rand() % 2)) { + if (stack.size() == 0 || (stack.size() < 4 && InsecureRandBool())) { CCoinsView* tip = &base; if (stack.size() > 0) { tip = stack.back(); @@ -433,53 +468,36 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test) BOOST_AUTO_TEST_CASE(ccoins_serialization) { // Good example - CDataStream ss1(ParseHex("0104835800816115944e077fe7c803cfa57f29b36bf87c1d358bb85e"), SER_DISK, CLIENT_VERSION); - CCoins cc1; + CDataStream ss1(ParseHex("97f23c835800816115944e077fe7c803cfa57f29b36bf87c1d35"), SER_DISK, CLIENT_VERSION); + Coin cc1; ss1 >> cc1; - BOOST_CHECK_EQUAL(cc1.nVersion, 1); BOOST_CHECK_EQUAL(cc1.fCoinBase, false); BOOST_CHECK_EQUAL(cc1.nHeight, 203998); - BOOST_CHECK_EQUAL(cc1.vout.size(), 2); - BOOST_CHECK_EQUAL(cc1.IsAvailable(0), false); - BOOST_CHECK_EQUAL(cc1.IsAvailable(1), true); - BOOST_CHECK_EQUAL(cc1.vout[1].nValue, 60000000000ULL); - BOOST_CHECK_EQUAL(HexStr(cc1.vout[1].scriptPubKey), HexStr(GetScriptForDestination(CKeyID(uint160(ParseHex("816115944e077fe7c803cfa57f29b36bf87c1d35")))))); + BOOST_CHECK_EQUAL(cc1.out.nValue, 60000000000ULL); + BOOST_CHECK_EQUAL(HexStr(cc1.out.scriptPubKey), HexStr(GetScriptForDestination(CKeyID(uint160(ParseHex("816115944e077fe7c803cfa57f29b36bf87c1d35")))))); // Good example - CDataStream ss2(ParseHex("0109044086ef97d5790061b01caab50f1b8e9c50a5057eb43c2d9563a4eebbd123008c988f1a4a4de2161e0f50aac7f17e7f9555caa486af3b"), SER_DISK, CLIENT_VERSION); - CCoins cc2; + CDataStream ss2(ParseHex("8ddf77bbd123008c988f1a4a4de2161e0f50aac7f17e7f9555caa4"), SER_DISK, CLIENT_VERSION); + Coin cc2; ss2 >> cc2; - BOOST_CHECK_EQUAL(cc2.nVersion, 1); BOOST_CHECK_EQUAL(cc2.fCoinBase, true); BOOST_CHECK_EQUAL(cc2.nHeight, 120891); - BOOST_CHECK_EQUAL(cc2.vout.size(), 17); - for (int i = 0; i < 17; i++) { - BOOST_CHECK_EQUAL(cc2.IsAvailable(i), i == 4 || i == 16); - } - BOOST_CHECK_EQUAL(cc2.vout[4].nValue, 234925952); - BOOST_CHECK_EQUAL(HexStr(cc2.vout[4].scriptPubKey), HexStr(GetScriptForDestination(CKeyID(uint160(ParseHex("61b01caab50f1b8e9c50a5057eb43c2d9563a4ee")))))); - BOOST_CHECK_EQUAL(cc2.vout[16].nValue, 110397); - BOOST_CHECK_EQUAL(HexStr(cc2.vout[16].scriptPubKey), HexStr(GetScriptForDestination(CKeyID(uint160(ParseHex("8c988f1a4a4de2161e0f50aac7f17e7f9555caa4")))))); + BOOST_CHECK_EQUAL(cc2.out.nValue, 110397); + BOOST_CHECK_EQUAL(HexStr(cc2.out.scriptPubKey), HexStr(GetScriptForDestination(CKeyID(uint160(ParseHex("8c988f1a4a4de2161e0f50aac7f17e7f9555caa4")))))); // Smallest possible example - CDataStream ssx(SER_DISK, CLIENT_VERSION); - BOOST_CHECK_EQUAL(HexStr(ssx.begin(), ssx.end()), ""); - - CDataStream ss3(ParseHex("0002000600"), SER_DISK, CLIENT_VERSION); - CCoins cc3; + CDataStream ss3(ParseHex("000006"), SER_DISK, CLIENT_VERSION); + Coin cc3; ss3 >> cc3; - BOOST_CHECK_EQUAL(cc3.nVersion, 0); BOOST_CHECK_EQUAL(cc3.fCoinBase, false); BOOST_CHECK_EQUAL(cc3.nHeight, 0); - BOOST_CHECK_EQUAL(cc3.vout.size(), 1); - BOOST_CHECK_EQUAL(cc3.IsAvailable(0), true); - BOOST_CHECK_EQUAL(cc3.vout[0].nValue, 0); - BOOST_CHECK_EQUAL(cc3.vout[0].scriptPubKey.size(), 0); + BOOST_CHECK_EQUAL(cc3.out.nValue, 0); + BOOST_CHECK_EQUAL(cc3.out.scriptPubKey.size(), 0); // scriptPubKey that ends beyond the end of the stream - CDataStream ss4(ParseHex("0002000800"), SER_DISK, CLIENT_VERSION); + CDataStream ss4(ParseHex("000007"), SER_DISK, CLIENT_VERSION); try { - CCoins cc4; + Coin cc4; ss4 >> cc4; BOOST_CHECK_MESSAGE(false, "We should have thrown"); } catch (const std::ios_base::failure& e) { @@ -490,16 +508,16 @@ BOOST_AUTO_TEST_CASE(ccoins_serialization) uint64_t x = 3000000000ULL; tmp << VARINT(x); BOOST_CHECK_EQUAL(HexStr(tmp.begin(), tmp.end()), "8a95c0bb00"); - CDataStream ss5(ParseHex("0002008a95c0bb0000"), SER_DISK, CLIENT_VERSION); + CDataStream ss5(ParseHex("00008a95c0bb00"), SER_DISK, CLIENT_VERSION); try { - CCoins cc5; + Coin cc5; ss5 >> cc5; BOOST_CHECK_MESSAGE(false, "We should have thrown"); } catch (const std::ios_base::failure& e) { } } -const static uint256 TXID; +const static COutPoint OUTPOINT; const static CAmount PRUNED = -1; const static CAmount ABSENT = -2; const static CAmount FAIL = -3; @@ -514,15 +532,15 @@ const static auto FLAGS = {char(0), FRESH, DIRTY, char(DIRTY | FRESH)}; const static auto CLEAN_FLAGS = {char(0), FRESH}; const static auto ABSENT_FLAGS = {NO_ENTRY}; -void SetCoinsValue(CAmount value, CCoins& coins) +void SetCoinsValue(CAmount value, Coin& coin) { assert(value != ABSENT); - coins.Clear(); - assert(coins.IsPruned()); + coin.Clear(); + assert(coin.IsSpent()); if (value != PRUNED) { - coins.vout.emplace_back(); - coins.vout.back().nValue = value; - assert(!coins.IsPruned()); + coin.out.nValue = value; + coin.nHeight = 1; + assert(!coin.IsSpent()); } } @@ -535,25 +553,23 @@ size_t InsertCoinsMapEntry(CCoinsMap& map, CAmount value, char flags) assert(flags != NO_ENTRY); CCoinsCacheEntry entry; entry.flags = flags; - SetCoinsValue(value, entry.coins); - auto inserted = map.emplace(TXID, std::move(entry)); + SetCoinsValue(value, entry.coin); + auto inserted = map.emplace(OUTPOINT, std::move(entry)); assert(inserted.second); - return inserted.first->second.coins.DynamicMemoryUsage(); + return inserted.first->second.coin.DynamicMemoryUsage(); } void GetCoinsMapEntry(const CCoinsMap& map, CAmount& value, char& flags) { - auto it = map.find(TXID); + auto it = map.find(OUTPOINT); if (it == map.end()) { value = ABSENT; flags = NO_ENTRY; } else { - if (it->second.coins.IsPruned()) { - assert(it->second.coins.vout.size() == 0); + if (it->second.coin.IsSpent()) { value = PRUNED; } else { - assert(it->second.coins.vout.size() == 1); - value = it->second.coins.vout[0].nValue; + value = it->second.coin.out.nValue; } flags = it->second.flags; assert(flags != NO_ENTRY); @@ -581,10 +597,10 @@ public: CCoinsViewCacheTest cache{&base}; }; -void CheckAccessCoins(CAmount base_value, CAmount cache_value, CAmount expected_value, char cache_flags, char expected_flags) +void CheckAccessCoin(CAmount base_value, CAmount cache_value, CAmount expected_value, char cache_flags, char expected_flags) { SingleEntryCacheTest test(base_value, cache_value, cache_flags); - test.cache.AccessCoins(TXID); + test.cache.AccessCoin(OUTPOINT); test.cache.SelfTest(); CAmount result_value; @@ -603,39 +619,39 @@ BOOST_AUTO_TEST_CASE(ccoins_access) * Base Cache Result Cache Result * Value Value Value Flags Flags */ - CheckAccessCoins(ABSENT, ABSENT, ABSENT, NO_ENTRY , NO_ENTRY ); - CheckAccessCoins(ABSENT, PRUNED, PRUNED, 0 , 0 ); - CheckAccessCoins(ABSENT, PRUNED, PRUNED, FRESH , FRESH ); - CheckAccessCoins(ABSENT, PRUNED, PRUNED, DIRTY , DIRTY ); - CheckAccessCoins(ABSENT, PRUNED, PRUNED, DIRTY|FRESH, DIRTY|FRESH); - CheckAccessCoins(ABSENT, VALUE2, VALUE2, 0 , 0 ); - CheckAccessCoins(ABSENT, VALUE2, VALUE2, FRESH , FRESH ); - CheckAccessCoins(ABSENT, VALUE2, VALUE2, DIRTY , DIRTY ); - CheckAccessCoins(ABSENT, VALUE2, VALUE2, DIRTY|FRESH, DIRTY|FRESH); - CheckAccessCoins(PRUNED, ABSENT, PRUNED, NO_ENTRY , FRESH ); - CheckAccessCoins(PRUNED, PRUNED, PRUNED, 0 , 0 ); - CheckAccessCoins(PRUNED, PRUNED, PRUNED, FRESH , FRESH ); - CheckAccessCoins(PRUNED, PRUNED, PRUNED, DIRTY , DIRTY ); - CheckAccessCoins(PRUNED, PRUNED, PRUNED, DIRTY|FRESH, DIRTY|FRESH); - CheckAccessCoins(PRUNED, VALUE2, VALUE2, 0 , 0 ); - CheckAccessCoins(PRUNED, VALUE2, VALUE2, FRESH , FRESH ); - CheckAccessCoins(PRUNED, VALUE2, VALUE2, DIRTY , DIRTY ); - CheckAccessCoins(PRUNED, VALUE2, VALUE2, DIRTY|FRESH, DIRTY|FRESH); - CheckAccessCoins(VALUE1, ABSENT, VALUE1, NO_ENTRY , 0 ); - CheckAccessCoins(VALUE1, PRUNED, PRUNED, 0 , 0 ); - CheckAccessCoins(VALUE1, PRUNED, PRUNED, FRESH , FRESH ); - CheckAccessCoins(VALUE1, PRUNED, PRUNED, DIRTY , DIRTY ); - CheckAccessCoins(VALUE1, PRUNED, PRUNED, DIRTY|FRESH, DIRTY|FRESH); - CheckAccessCoins(VALUE1, VALUE2, VALUE2, 0 , 0 ); - CheckAccessCoins(VALUE1, VALUE2, VALUE2, FRESH , FRESH ); - CheckAccessCoins(VALUE1, VALUE2, VALUE2, DIRTY , DIRTY ); - CheckAccessCoins(VALUE1, VALUE2, VALUE2, DIRTY|FRESH, DIRTY|FRESH); + CheckAccessCoin(ABSENT, ABSENT, ABSENT, NO_ENTRY , NO_ENTRY ); + CheckAccessCoin(ABSENT, PRUNED, PRUNED, 0 , 0 ); + CheckAccessCoin(ABSENT, PRUNED, PRUNED, FRESH , FRESH ); + CheckAccessCoin(ABSENT, PRUNED, PRUNED, DIRTY , DIRTY ); + CheckAccessCoin(ABSENT, PRUNED, PRUNED, DIRTY|FRESH, DIRTY|FRESH); + CheckAccessCoin(ABSENT, VALUE2, VALUE2, 0 , 0 ); + CheckAccessCoin(ABSENT, VALUE2, VALUE2, FRESH , FRESH ); + CheckAccessCoin(ABSENT, VALUE2, VALUE2, DIRTY , DIRTY ); + CheckAccessCoin(ABSENT, VALUE2, VALUE2, DIRTY|FRESH, DIRTY|FRESH); + CheckAccessCoin(PRUNED, ABSENT, PRUNED, NO_ENTRY , FRESH ); + CheckAccessCoin(PRUNED, PRUNED, PRUNED, 0 , 0 ); + CheckAccessCoin(PRUNED, PRUNED, PRUNED, FRESH , FRESH ); + CheckAccessCoin(PRUNED, PRUNED, PRUNED, DIRTY , DIRTY ); + CheckAccessCoin(PRUNED, PRUNED, PRUNED, DIRTY|FRESH, DIRTY|FRESH); + CheckAccessCoin(PRUNED, VALUE2, VALUE2, 0 , 0 ); + CheckAccessCoin(PRUNED, VALUE2, VALUE2, FRESH , FRESH ); + CheckAccessCoin(PRUNED, VALUE2, VALUE2, DIRTY , DIRTY ); + CheckAccessCoin(PRUNED, VALUE2, VALUE2, DIRTY|FRESH, DIRTY|FRESH); + CheckAccessCoin(VALUE1, ABSENT, VALUE1, NO_ENTRY , 0 ); + CheckAccessCoin(VALUE1, PRUNED, PRUNED, 0 , 0 ); + CheckAccessCoin(VALUE1, PRUNED, PRUNED, FRESH , FRESH ); + CheckAccessCoin(VALUE1, PRUNED, PRUNED, DIRTY , DIRTY ); + CheckAccessCoin(VALUE1, PRUNED, PRUNED, DIRTY|FRESH, DIRTY|FRESH); + CheckAccessCoin(VALUE1, VALUE2, VALUE2, 0 , 0 ); + CheckAccessCoin(VALUE1, VALUE2, VALUE2, FRESH , FRESH ); + CheckAccessCoin(VALUE1, VALUE2, VALUE2, DIRTY , DIRTY ); + CheckAccessCoin(VALUE1, VALUE2, VALUE2, DIRTY|FRESH, DIRTY|FRESH); } -void CheckModifyCoins(CAmount base_value, CAmount cache_value, CAmount modify_value, CAmount expected_value, char cache_flags, char expected_flags) +void CheckSpendCoins(CAmount base_value, CAmount cache_value, CAmount expected_value, char cache_flags, char expected_flags) { SingleEntryCacheTest test(base_value, cache_value, cache_flags); - SetCoinsValue(modify_value, *test.cache.ModifyCoins(TXID)); + test.cache.SpendCoin(OUTPOINT); test.cache.SelfTest(); CAmount result_value; @@ -645,79 +661,55 @@ void CheckModifyCoins(CAmount base_value, CAmount cache_value, CAmount modify_va BOOST_CHECK_EQUAL(result_flags, expected_flags); }; -BOOST_AUTO_TEST_CASE(ccoins_modify) +BOOST_AUTO_TEST_CASE(ccoins_spend) { - /* Check ModifyCoin behavior, requesting a coin from a cache view layered on - * top of a base view, writing a modification to the coin, and then checking + /* Check SpendCoin behavior, requesting a coin from a cache view layered on + * top of a base view, spending, and then checking * the resulting entry in the cache after the modification. * - * Base Cache Write Result Cache Result - * Value Value Value Value Flags Flags + * Base Cache Result Cache Result + * Value Value Value Flags Flags */ - CheckModifyCoins(ABSENT, ABSENT, PRUNED, ABSENT, NO_ENTRY , NO_ENTRY ); - CheckModifyCoins(ABSENT, ABSENT, VALUE3, VALUE3, NO_ENTRY , DIRTY|FRESH); - CheckModifyCoins(ABSENT, PRUNED, PRUNED, PRUNED, 0 , DIRTY ); - CheckModifyCoins(ABSENT, PRUNED, PRUNED, ABSENT, FRESH , NO_ENTRY ); - CheckModifyCoins(ABSENT, PRUNED, PRUNED, PRUNED, DIRTY , DIRTY ); - CheckModifyCoins(ABSENT, PRUNED, PRUNED, ABSENT, DIRTY|FRESH, NO_ENTRY ); - CheckModifyCoins(ABSENT, PRUNED, VALUE3, VALUE3, 0 , DIRTY ); - CheckModifyCoins(ABSENT, PRUNED, VALUE3, VALUE3, FRESH , DIRTY|FRESH); - CheckModifyCoins(ABSENT, PRUNED, VALUE3, VALUE3, DIRTY , DIRTY ); - CheckModifyCoins(ABSENT, PRUNED, VALUE3, VALUE3, DIRTY|FRESH, DIRTY|FRESH); - CheckModifyCoins(ABSENT, VALUE2, PRUNED, PRUNED, 0 , DIRTY ); - CheckModifyCoins(ABSENT, VALUE2, PRUNED, ABSENT, FRESH , NO_ENTRY ); - CheckModifyCoins(ABSENT, VALUE2, PRUNED, PRUNED, DIRTY , DIRTY ); - CheckModifyCoins(ABSENT, VALUE2, PRUNED, ABSENT, DIRTY|FRESH, NO_ENTRY ); - CheckModifyCoins(ABSENT, VALUE2, VALUE3, VALUE3, 0 , DIRTY ); - CheckModifyCoins(ABSENT, VALUE2, VALUE3, VALUE3, FRESH , DIRTY|FRESH); - CheckModifyCoins(ABSENT, VALUE2, VALUE3, VALUE3, DIRTY , DIRTY ); - CheckModifyCoins(ABSENT, VALUE2, VALUE3, VALUE3, DIRTY|FRESH, DIRTY|FRESH); - CheckModifyCoins(PRUNED, ABSENT, PRUNED, ABSENT, NO_ENTRY , NO_ENTRY ); - CheckModifyCoins(PRUNED, ABSENT, VALUE3, VALUE3, NO_ENTRY , DIRTY|FRESH); - CheckModifyCoins(PRUNED, PRUNED, PRUNED, PRUNED, 0 , DIRTY ); - CheckModifyCoins(PRUNED, PRUNED, PRUNED, ABSENT, FRESH , NO_ENTRY ); - CheckModifyCoins(PRUNED, PRUNED, PRUNED, PRUNED, DIRTY , DIRTY ); - CheckModifyCoins(PRUNED, PRUNED, PRUNED, ABSENT, DIRTY|FRESH, NO_ENTRY ); - CheckModifyCoins(PRUNED, PRUNED, VALUE3, VALUE3, 0 , DIRTY ); - CheckModifyCoins(PRUNED, PRUNED, VALUE3, VALUE3, FRESH , DIRTY|FRESH); - CheckModifyCoins(PRUNED, PRUNED, VALUE3, VALUE3, DIRTY , DIRTY ); - CheckModifyCoins(PRUNED, PRUNED, VALUE3, VALUE3, DIRTY|FRESH, DIRTY|FRESH); - CheckModifyCoins(PRUNED, VALUE2, PRUNED, PRUNED, 0 , DIRTY ); - CheckModifyCoins(PRUNED, VALUE2, PRUNED, ABSENT, FRESH , NO_ENTRY ); - CheckModifyCoins(PRUNED, VALUE2, PRUNED, PRUNED, DIRTY , DIRTY ); - CheckModifyCoins(PRUNED, VALUE2, PRUNED, ABSENT, DIRTY|FRESH, NO_ENTRY ); - CheckModifyCoins(PRUNED, VALUE2, VALUE3, VALUE3, 0 , DIRTY ); - CheckModifyCoins(PRUNED, VALUE2, VALUE3, VALUE3, FRESH , DIRTY|FRESH); - CheckModifyCoins(PRUNED, VALUE2, VALUE3, VALUE3, DIRTY , DIRTY ); - CheckModifyCoins(PRUNED, VALUE2, VALUE3, VALUE3, DIRTY|FRESH, DIRTY|FRESH); - CheckModifyCoins(VALUE1, ABSENT, PRUNED, PRUNED, NO_ENTRY , DIRTY ); - CheckModifyCoins(VALUE1, ABSENT, VALUE3, VALUE3, NO_ENTRY , DIRTY ); - CheckModifyCoins(VALUE1, PRUNED, PRUNED, PRUNED, 0 , DIRTY ); - CheckModifyCoins(VALUE1, PRUNED, PRUNED, ABSENT, FRESH , NO_ENTRY ); - CheckModifyCoins(VALUE1, PRUNED, PRUNED, PRUNED, DIRTY , DIRTY ); - CheckModifyCoins(VALUE1, PRUNED, PRUNED, ABSENT, DIRTY|FRESH, NO_ENTRY ); - CheckModifyCoins(VALUE1, PRUNED, VALUE3, VALUE3, 0 , DIRTY ); - CheckModifyCoins(VALUE1, PRUNED, VALUE3, VALUE3, FRESH , DIRTY|FRESH); - CheckModifyCoins(VALUE1, PRUNED, VALUE3, VALUE3, DIRTY , DIRTY ); - CheckModifyCoins(VALUE1, PRUNED, VALUE3, VALUE3, DIRTY|FRESH, DIRTY|FRESH); - CheckModifyCoins(VALUE1, VALUE2, PRUNED, PRUNED, 0 , DIRTY ); - CheckModifyCoins(VALUE1, VALUE2, PRUNED, ABSENT, FRESH , NO_ENTRY ); - CheckModifyCoins(VALUE1, VALUE2, PRUNED, PRUNED, DIRTY , DIRTY ); - CheckModifyCoins(VALUE1, VALUE2, PRUNED, ABSENT, DIRTY|FRESH, NO_ENTRY ); - CheckModifyCoins(VALUE1, VALUE2, VALUE3, VALUE3, 0 , DIRTY ); - CheckModifyCoins(VALUE1, VALUE2, VALUE3, VALUE3, FRESH , DIRTY|FRESH); - CheckModifyCoins(VALUE1, VALUE2, VALUE3, VALUE3, DIRTY , DIRTY ); - CheckModifyCoins(VALUE1, VALUE2, VALUE3, VALUE3, DIRTY|FRESH, DIRTY|FRESH); + CheckSpendCoins(ABSENT, ABSENT, ABSENT, NO_ENTRY , NO_ENTRY ); + CheckSpendCoins(ABSENT, PRUNED, PRUNED, 0 , DIRTY ); + CheckSpendCoins(ABSENT, PRUNED, ABSENT, FRESH , NO_ENTRY ); + CheckSpendCoins(ABSENT, PRUNED, PRUNED, DIRTY , DIRTY ); + CheckSpendCoins(ABSENT, PRUNED, ABSENT, DIRTY|FRESH, NO_ENTRY ); + CheckSpendCoins(ABSENT, VALUE2, PRUNED, 0 , DIRTY ); + CheckSpendCoins(ABSENT, VALUE2, ABSENT, FRESH , NO_ENTRY ); + CheckSpendCoins(ABSENT, VALUE2, PRUNED, DIRTY , DIRTY ); + CheckSpendCoins(ABSENT, VALUE2, ABSENT, DIRTY|FRESH, NO_ENTRY ); + CheckSpendCoins(PRUNED, ABSENT, ABSENT, NO_ENTRY , NO_ENTRY ); + CheckSpendCoins(PRUNED, PRUNED, PRUNED, 0 , DIRTY ); + CheckSpendCoins(PRUNED, PRUNED, ABSENT, FRESH , NO_ENTRY ); + CheckSpendCoins(PRUNED, PRUNED, PRUNED, DIRTY , DIRTY ); + CheckSpendCoins(PRUNED, PRUNED, ABSENT, DIRTY|FRESH, NO_ENTRY ); + CheckSpendCoins(PRUNED, VALUE2, PRUNED, 0 , DIRTY ); + CheckSpendCoins(PRUNED, VALUE2, ABSENT, FRESH , NO_ENTRY ); + CheckSpendCoins(PRUNED, VALUE2, PRUNED, DIRTY , DIRTY ); + CheckSpendCoins(PRUNED, VALUE2, ABSENT, DIRTY|FRESH, NO_ENTRY ); + CheckSpendCoins(VALUE1, ABSENT, PRUNED, NO_ENTRY , DIRTY ); + CheckSpendCoins(VALUE1, PRUNED, PRUNED, 0 , DIRTY ); + CheckSpendCoins(VALUE1, PRUNED, ABSENT, FRESH , NO_ENTRY ); + CheckSpendCoins(VALUE1, PRUNED, PRUNED, DIRTY , DIRTY ); + CheckSpendCoins(VALUE1, PRUNED, ABSENT, DIRTY|FRESH, NO_ENTRY ); + CheckSpendCoins(VALUE1, VALUE2, PRUNED, 0 , DIRTY ); + CheckSpendCoins(VALUE1, VALUE2, ABSENT, FRESH , NO_ENTRY ); + CheckSpendCoins(VALUE1, VALUE2, PRUNED, DIRTY , DIRTY ); + CheckSpendCoins(VALUE1, VALUE2, ABSENT, DIRTY|FRESH, NO_ENTRY ); } -void CheckModifyNewCoinsBase(CAmount base_value, CAmount cache_value, CAmount modify_value, CAmount expected_value, char cache_flags, char expected_flags, bool coinbase) +void CheckAddCoinBase(CAmount base_value, CAmount cache_value, CAmount modify_value, CAmount expected_value, char cache_flags, char expected_flags, bool coinbase) { SingleEntryCacheTest test(base_value, cache_value, cache_flags); CAmount result_value; char result_flags; try { - SetCoinsValue(modify_value, *test.cache.ModifyNewCoins(TXID, coinbase)); + CTxOut output; + output.nValue = modify_value; + test.cache.AddCoin(OUTPOINT, Coin(std::move(output), 1, coinbase), coinbase); + test.cache.SelfTest(); GetCoinsMapEntry(test.cache.map(), result_value, result_flags); } catch (std::logic_error& e) { result_value = FAIL; @@ -728,64 +720,46 @@ void CheckModifyNewCoinsBase(CAmount base_value, CAmount cache_value, CAmount mo BOOST_CHECK_EQUAL(result_flags, expected_flags); } -// Simple wrapper for CheckModifyNewCoinsBase function above that loops through +// Simple wrapper for CheckAddCoinBase function above that loops through // different possible base_values, making sure each one gives the same results. -// This wrapper lets the modify_new test below be shorter and less repetitive, -// while still verifying that the CoinsViewCache::ModifyNewCoins implementation +// This wrapper lets the coins_add test below be shorter and less repetitive, +// while still verifying that the CoinsViewCache::AddCoin implementation // ignores base values. template <typename... Args> -void CheckModifyNewCoins(Args&&... args) +void CheckAddCoin(Args&&... args) { for (CAmount base_value : {ABSENT, PRUNED, VALUE1}) - CheckModifyNewCoinsBase(base_value, std::forward<Args>(args)...); + CheckAddCoinBase(base_value, std::forward<Args>(args)...); } -BOOST_AUTO_TEST_CASE(ccoins_modify_new) +BOOST_AUTO_TEST_CASE(ccoins_add) { - /* Check ModifyNewCoin behavior, requesting a new coin from a cache view, + /* Check AddCoin behavior, requesting a new coin from a cache view, * writing a modification to the coin, and then checking the resulting * entry in the cache after the modification. Verify behavior with the - * with the ModifyNewCoin coinbase argument set to false, and to true. + * with the AddCoin potential_overwrite argument set to false, and to true. * - * Cache Write Result Cache Result Coinbase - * Value Value Value Flags Flags + * Cache Write Result Cache Result potential_overwrite + * Value Value Value Flags Flags */ - CheckModifyNewCoins(ABSENT, PRUNED, ABSENT, NO_ENTRY , NO_ENTRY , false); - CheckModifyNewCoins(ABSENT, PRUNED, PRUNED, NO_ENTRY , DIRTY , true ); - CheckModifyNewCoins(ABSENT, VALUE3, VALUE3, NO_ENTRY , DIRTY|FRESH, false); - CheckModifyNewCoins(ABSENT, VALUE3, VALUE3, NO_ENTRY , DIRTY , true ); - CheckModifyNewCoins(PRUNED, PRUNED, ABSENT, 0 , NO_ENTRY , false); - CheckModifyNewCoins(PRUNED, PRUNED, PRUNED, 0 , DIRTY , true ); - CheckModifyNewCoins(PRUNED, PRUNED, ABSENT, FRESH , NO_ENTRY , false); - CheckModifyNewCoins(PRUNED, PRUNED, ABSENT, FRESH , NO_ENTRY , true ); - CheckModifyNewCoins(PRUNED, PRUNED, PRUNED, DIRTY , DIRTY , false); - CheckModifyNewCoins(PRUNED, PRUNED, PRUNED, DIRTY , DIRTY , true ); - CheckModifyNewCoins(PRUNED, PRUNED, ABSENT, DIRTY|FRESH, NO_ENTRY , false); - CheckModifyNewCoins(PRUNED, PRUNED, ABSENT, DIRTY|FRESH, NO_ENTRY , true ); - CheckModifyNewCoins(PRUNED, VALUE3, VALUE3, 0 , DIRTY|FRESH, false); - CheckModifyNewCoins(PRUNED, VALUE3, VALUE3, 0 , DIRTY , true ); - CheckModifyNewCoins(PRUNED, VALUE3, VALUE3, FRESH , DIRTY|FRESH, false); - CheckModifyNewCoins(PRUNED, VALUE3, VALUE3, FRESH , DIRTY|FRESH, true ); - CheckModifyNewCoins(PRUNED, VALUE3, VALUE3, DIRTY , DIRTY , false); - CheckModifyNewCoins(PRUNED, VALUE3, VALUE3, DIRTY , DIRTY , true ); - CheckModifyNewCoins(PRUNED, VALUE3, VALUE3, DIRTY|FRESH, DIRTY|FRESH, false); - CheckModifyNewCoins(PRUNED, VALUE3, VALUE3, DIRTY|FRESH, DIRTY|FRESH, true ); - CheckModifyNewCoins(VALUE2, PRUNED, FAIL , 0 , NO_ENTRY , false); - CheckModifyNewCoins(VALUE2, PRUNED, PRUNED, 0 , DIRTY , true ); - CheckModifyNewCoins(VALUE2, PRUNED, FAIL , FRESH , NO_ENTRY , false); - CheckModifyNewCoins(VALUE2, PRUNED, ABSENT, FRESH , NO_ENTRY , true ); - CheckModifyNewCoins(VALUE2, PRUNED, FAIL , DIRTY , NO_ENTRY , false); - CheckModifyNewCoins(VALUE2, PRUNED, PRUNED, DIRTY , DIRTY , true ); - CheckModifyNewCoins(VALUE2, PRUNED, FAIL , DIRTY|FRESH, NO_ENTRY , false); - CheckModifyNewCoins(VALUE2, PRUNED, ABSENT, DIRTY|FRESH, NO_ENTRY , true ); - CheckModifyNewCoins(VALUE2, VALUE3, FAIL , 0 , NO_ENTRY , false); - CheckModifyNewCoins(VALUE2, VALUE3, VALUE3, 0 , DIRTY , true ); - CheckModifyNewCoins(VALUE2, VALUE3, FAIL , FRESH , NO_ENTRY , false); - CheckModifyNewCoins(VALUE2, VALUE3, VALUE3, FRESH , DIRTY|FRESH, true ); - CheckModifyNewCoins(VALUE2, VALUE3, FAIL , DIRTY , NO_ENTRY , false); - CheckModifyNewCoins(VALUE2, VALUE3, VALUE3, DIRTY , DIRTY , true ); - CheckModifyNewCoins(VALUE2, VALUE3, FAIL , DIRTY|FRESH, NO_ENTRY , false); - CheckModifyNewCoins(VALUE2, VALUE3, VALUE3, DIRTY|FRESH, DIRTY|FRESH, true ); + CheckAddCoin(ABSENT, VALUE3, VALUE3, NO_ENTRY , DIRTY|FRESH, false); + CheckAddCoin(ABSENT, VALUE3, VALUE3, NO_ENTRY , DIRTY , true ); + CheckAddCoin(PRUNED, VALUE3, VALUE3, 0 , DIRTY|FRESH, false); + CheckAddCoin(PRUNED, VALUE3, VALUE3, 0 , DIRTY , true ); + CheckAddCoin(PRUNED, VALUE3, VALUE3, FRESH , DIRTY|FRESH, false); + CheckAddCoin(PRUNED, VALUE3, VALUE3, FRESH , DIRTY|FRESH, true ); + CheckAddCoin(PRUNED, VALUE3, VALUE3, DIRTY , DIRTY , false); + CheckAddCoin(PRUNED, VALUE3, VALUE3, DIRTY , DIRTY , true ); + CheckAddCoin(PRUNED, VALUE3, VALUE3, DIRTY|FRESH, DIRTY|FRESH, false); + CheckAddCoin(PRUNED, VALUE3, VALUE3, DIRTY|FRESH, DIRTY|FRESH, true ); + CheckAddCoin(VALUE2, VALUE3, FAIL , 0 , NO_ENTRY , false); + CheckAddCoin(VALUE2, VALUE3, VALUE3, 0 , DIRTY , true ); + CheckAddCoin(VALUE2, VALUE3, FAIL , FRESH , NO_ENTRY , false); + CheckAddCoin(VALUE2, VALUE3, VALUE3, FRESH , DIRTY|FRESH, true ); + CheckAddCoin(VALUE2, VALUE3, FAIL , DIRTY , NO_ENTRY , false); + CheckAddCoin(VALUE2, VALUE3, VALUE3, DIRTY , DIRTY , true ); + CheckAddCoin(VALUE2, VALUE3, FAIL , DIRTY|FRESH, NO_ENTRY , false); + CheckAddCoin(VALUE2, VALUE3, VALUE3, DIRTY|FRESH, DIRTY|FRESH, true ); } void CheckWriteCoins(CAmount parent_value, CAmount child_value, CAmount expected_value, char parent_flags, char child_flags, char expected_flags) diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp index 72e562808a..391ad14ffa 100644 --- a/src/test/crypto_tests.cpp +++ b/src/test/crypto_tests.cpp @@ -13,11 +13,9 @@ #include "random.h" #include "utilstrencodings.h" #include "test/test_bitcoin.h" -#include "test/test_random.h" #include <vector> -#include <boost/assign/list_of.hpp> #include <boost/test/unit_test.hpp> #include <openssl/aes.h> #include <openssl/evp.h> @@ -39,7 +37,7 @@ void TestVector(const Hasher &h, const In &in, const Out &out) { Hasher hasher(h); size_t pos = 0; while (pos < in.size()) { - size_t len = insecure_rand() % ((in.size() - pos + 1) / 2 + 1); + size_t len = InsecureRandRange((in.size() - pos + 1) / 2 + 1); hasher.Write((unsigned char*)&in[pos], len); pos += len; if (pos > 0 && pos + 2 * out.size() > in.size() && pos < in.size()) { diff --git a/src/test/cuckoocache_tests.cpp b/src/test/cuckoocache_tests.cpp index 8cae4e66e8..1004482224 100644 --- a/src/test/cuckoocache_tests.cpp +++ b/src/test/cuckoocache_tests.cpp @@ -7,8 +7,6 @@ #include "test/test_bitcoin.h" #include "random.h" #include <thread> -#include <boost/thread.hpp> - /** Test Suite for CuckooCache * @@ -23,18 +21,18 @@ * using BOOST_CHECK_CLOSE to fail. * */ -FastRandomContext insecure_rand(true); +FastRandomContext local_rand_ctx(true); BOOST_AUTO_TEST_SUITE(cuckoocache_tests); -/** insecure_GetRandHash fills in a uint256 from insecure_rand +/** insecure_GetRandHash fills in a uint256 from local_rand_ctx */ void insecure_GetRandHash(uint256& t) { uint32_t* ptr = (uint32_t*)t.begin(); for (uint8_t j = 0; j < 8; ++j) - *(ptr++) = insecure_rand.rand32(); + *(ptr++) = local_rand_ctx.rand32(); } @@ -45,7 +43,7 @@ void insecure_GetRandHash(uint256& t) */ BOOST_AUTO_TEST_CASE(test_cuckoocache_no_fakes) { - insecure_rand = FastRandomContext(true); + local_rand_ctx = FastRandomContext(true); CuckooCache::cache<uint256, SignatureCacheHasher> cc{}; size_t megabytes = 4; cc.setup_bytes(megabytes << 20); @@ -66,7 +64,7 @@ BOOST_AUTO_TEST_CASE(test_cuckoocache_no_fakes) template <typename Cache> double test_cache(size_t megabytes, double load) { - insecure_rand = FastRandomContext(true); + local_rand_ctx = FastRandomContext(true); std::vector<uint256> hashes; Cache set{}; size_t bytes = megabytes * (1 << 20); @@ -76,7 +74,7 @@ double test_cache(size_t megabytes, double load) for (uint32_t i = 0; i < n_insert; ++i) { uint32_t* ptr = (uint32_t*)hashes[i].begin(); for (uint8_t j = 0; j < 8; ++j) - *(ptr++) = insecure_rand.rand32(); + *(ptr++) = local_rand_ctx.rand32(); } /** We make a copy of the hashes because future optimizations of the * cuckoocache may overwrite the inserted element, so the test is @@ -137,7 +135,7 @@ template <typename Cache> void test_cache_erase(size_t megabytes) { double load = 1; - insecure_rand = FastRandomContext(true); + local_rand_ctx = FastRandomContext(true); std::vector<uint256> hashes; Cache set{}; size_t bytes = megabytes * (1 << 20); @@ -147,7 +145,7 @@ void test_cache_erase(size_t megabytes) for (uint32_t i = 0; i < n_insert; ++i) { uint32_t* ptr = (uint32_t*)hashes[i].begin(); for (uint8_t j = 0; j < 8; ++j) - *(ptr++) = insecure_rand.rand32(); + *(ptr++) = local_rand_ctx.rand32(); } /** We make a copy of the hashes because future optimizations of the * cuckoocache may overwrite the inserted element, so the test is @@ -200,7 +198,7 @@ template <typename Cache> void test_cache_erase_parallel(size_t megabytes) { double load = 1; - insecure_rand = FastRandomContext(true); + local_rand_ctx = FastRandomContext(true); std::vector<uint256> hashes; Cache set{}; size_t bytes = megabytes * (1 << 20); @@ -210,7 +208,7 @@ void test_cache_erase_parallel(size_t megabytes) for (uint32_t i = 0; i < n_insert; ++i) { uint32_t* ptr = (uint32_t*)hashes[i].begin(); for (uint8_t j = 0; j < 8; ++j) - *(ptr++) = insecure_rand.rand32(); + *(ptr++) = local_rand_ctx.rand32(); } /** We make a copy of the hashes because future optimizations of the * cuckoocache may overwrite the inserted element, so the test is @@ -302,7 +300,7 @@ void test_cache_generations() // iterations with non-deterministic values, so it isn't "overfit" to the // specific entropy in FastRandomContext(true) and implementation of the // cache. - insecure_rand = FastRandomContext(true); + local_rand_ctx = FastRandomContext(true); // block_activity models a chunk of network activity. n_insert elements are // adde to the cache. The first and last n/4 are stored for removal later @@ -319,7 +317,7 @@ void test_cache_generations() for (uint32_t i = 0; i < n_insert; ++i) { uint32_t* ptr = (uint32_t*)inserts[i].begin(); for (uint8_t j = 0; j < 8; ++j) - *(ptr++) = insecure_rand.rand32(); + *(ptr++) = local_rand_ctx.rand32(); } for (uint32_t i = 0; i < n_insert / 4; ++i) reads.push_back(inserts[i]); diff --git a/src/test/data/script_tests.json b/src/test/data/script_tests.json index 5c054ed3e8..0390d6806d 100644 --- a/src/test/data/script_tests.json +++ b/src/test/data/script_tests.json @@ -349,7 +349,7 @@ ["2147483647", "0x04 0xFFFFFF7F EQUAL", "P2SH,STRICTENC", "OK"], ["2147483648", "0x05 0x0000008000 EQUAL", "P2SH,STRICTENC", "OK"], ["549755813887", "0x05 0xFFFFFFFF7F EQUAL", "P2SH,STRICTENC", "OK"], -["549755813888", "0x06 0xFFFFFFFF7F EQUAL", "P2SH,STRICTENC", "OK"], +["549755813888", "0x06 0x000000008000 EQUAL", "P2SH,STRICTENC", "OK"], ["9223372036854775807", "0x08 0xFFFFFFFFFFFFFF7F EQUAL", "P2SH,STRICTENC", "OK"], ["-1", "0x01 0x81 EQUAL", "P2SH,STRICTENC", "OK", "Numbers are little-endian with the MSB being a sign bit"], ["-127", "0x01 0xFF EQUAL", "P2SH,STRICTENC", "OK"], @@ -2506,7 +2506,7 @@ ], ["CHECKSEQUENCEVERIFY tests"], -["", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "INVALID_STACK_OPERATION", "CSV automatically fails on a empty stack"], +["", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "INVALID_STACK_OPERATION", "CSV automatically fails on an empty stack"], ["-1", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "NEGATIVE_LOCKTIME", "CSV automatically fails if stack top is negative"], ["0x0100", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY,MINIMALDATA", "UNKNOWN_ERROR", "CSV fails if stack top is not minimally encoded"], ["0", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "UNSATISFIED_LOCKTIME", "CSV fails if stack top bit 1 << 31 is set and the tx version < 2"], diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json index d70fa54333..e6b382af13 100644 --- a/src/test/data/tx_valid.json +++ b/src/test/data/tx_valid.json @@ -174,7 +174,7 @@ [[["5a6b0021a6042a686b6b94abc36b387bef9109847774e8b1e51eb8cc55c53921", 1, "DUP HASH160 0x14 0xee5a6aa40facefb2655ac23c0c28c57c65c41f9b EQUALVERIFY CHECKSIG"]], "01000000012139c555ccb81ee5b1e87477840991ef7b386bc3ab946b6b682a04a621006b5a01000000fdb40148304502201723e692e5f409a7151db386291b63524c5eb2030df652b1f53022fd8207349f022100b90d9bbf2f3366ce176e5e780a00433da67d9e5c79312c6388312a296a5800390148304502201723e692e5f409a7151db386291b63524c5eb2030df652b1f53022fd8207349f022100b90d9bbf2f3366ce176e5e780a00433da67d9e5c79312c6388312a296a5800390121038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f2204148304502201723e692e5f409a7151db386291b63524c5eb2030df652b1f53022fd8207349f022100b90d9bbf2f3366ce176e5e780a00433da67d9e5c79312c6388312a296a5800390175ac4830450220646b72c35beeec51f4d5bc1cbae01863825750d7f490864af354e6ea4f625e9c022100f04b98432df3a9641719dbced53393022e7249fb59db993af1118539830aab870148304502201723e692e5f409a7151db386291b63524c5eb2030df652b1f53022fd8207349f022100b90d9bbf2f3366ce176e5e780a00433da67d9e5c79312c6388312a296a580039017521038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041ffffffff010000000000000000016a00000000", "P2SH"], -["Finally CHECKMULTISIG removes all signatures prior to hashing the script containing those signatures. In conjunction with the SIGHASH_SINGLE bug this lets us test whether or not FindAndDelete() is actually present in scriptPubKey/redeemScript evaluation by including a signature of the digest 0x01 We can compute in advance for our pubkey, embed it it in the scriptPubKey, and then also using a normal SIGHASH_ALL signature. If FindAndDelete() wasn't run, the 'bugged' signature would still be in the hashed script, and the normal signature would fail."], +["Finally CHECKMULTISIG removes all signatures prior to hashing the script containing those signatures. In conjunction with the SIGHASH_SINGLE bug this lets us test whether or not FindAndDelete() is actually present in scriptPubKey/redeemScript evaluation by including a signature of the digest 0x01 We can compute in advance for our pubkey, embed it in the scriptPubKey, and then also using a normal SIGHASH_ALL signature. If FindAndDelete() wasn't run, the 'bugged' signature would still be in the hashed script, and the normal signature would fail."], ["Here's an example on mainnet within a P2SH redeemScript. Remarkably it's a standard transaction in <0.9"], [[["b5b598de91787439afd5938116654e0b16b7a0d0f82742ba37564219c5afcbf9", 0, "DUP HASH160 0x14 0xf6f365c40f0739b61de827a44751e5e99032ed8f EQUALVERIFY CHECKSIG"], diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp index c9d9849ada..be631ce7a6 100644 --- a/src/test/dbwrapper_tests.cpp +++ b/src/test/dbwrapper_tests.cpp @@ -7,8 +7,6 @@ #include "random.h" #include "test/test_bitcoin.h" -#include <boost/assign/std/vector.hpp> // for 'operator+=()' -#include <boost/assert.hpp> #include <boost/test/unit_test.hpp> // Test if a string consists entirely of null characters @@ -31,7 +29,7 @@ BOOST_AUTO_TEST_CASE(dbwrapper) fs::path ph = fs::temp_directory_path() / fs::unique_path(); CDBWrapper dbw(ph, (1 << 20), true, false, obfuscate); char key = 'k'; - uint256 in = GetRandHash(); + uint256 in = InsecureRand256(); uint256 res; // Ensure that we're doing real obfuscation when obfuscate=true @@ -53,11 +51,11 @@ BOOST_AUTO_TEST_CASE(dbwrapper_batch) CDBWrapper dbw(ph, (1 << 20), true, false, obfuscate); char key = 'i'; - uint256 in = GetRandHash(); + uint256 in = InsecureRand256(); char key2 = 'j'; - uint256 in2 = GetRandHash(); + uint256 in2 = InsecureRand256(); char key3 = 'k'; - uint256 in3 = GetRandHash(); + uint256 in3 = InsecureRand256(); uint256 res; CDBBatch batch(dbw); @@ -91,10 +89,10 @@ BOOST_AUTO_TEST_CASE(dbwrapper_iterator) // The two keys are intentionally chosen for ordering char key = 'j'; - uint256 in = GetRandHash(); + uint256 in = InsecureRand256(); BOOST_CHECK(dbw.Write(key, in)); char key2 = 'k'; - uint256 in2 = GetRandHash(); + uint256 in2 = InsecureRand256(); BOOST_CHECK(dbw.Write(key2, in2)); std::unique_ptr<CDBIterator> it(const_cast<CDBWrapper*>(&dbw)->NewIterator()); @@ -132,7 +130,7 @@ BOOST_AUTO_TEST_CASE(existing_data_no_obfuscate) // Set up a non-obfuscated wrapper to write some initial data. CDBWrapper* dbw = new CDBWrapper(ph, (1 << 10), false, false, false); char key = 'k'; - uint256 in = GetRandHash(); + uint256 in = InsecureRand256(); uint256 res; BOOST_CHECK(dbw->Write(key, in)); @@ -155,7 +153,7 @@ BOOST_AUTO_TEST_CASE(existing_data_no_obfuscate) BOOST_CHECK(!odbw.IsEmpty()); // There should be existing data BOOST_CHECK(is_null_key(dbwrapper_private::GetObfuscateKey(odbw))); // The key should be an empty string - uint256 in2 = GetRandHash(); + uint256 in2 = InsecureRand256(); uint256 res3; // Check that we can write successfully @@ -174,7 +172,7 @@ BOOST_AUTO_TEST_CASE(existing_data_reindex) // Set up a non-obfuscated wrapper to write some initial data. CDBWrapper* dbw = new CDBWrapper(ph, (1 << 10), false, false, false); char key = 'k'; - uint256 in = GetRandHash(); + uint256 in = InsecureRand256(); uint256 res; BOOST_CHECK(dbw->Write(key, in)); @@ -193,7 +191,7 @@ BOOST_AUTO_TEST_CASE(existing_data_reindex) BOOST_CHECK(!odbw.Read(key, res2)); BOOST_CHECK(!is_null_key(dbwrapper_private::GetObfuscateKey(odbw))); - uint256 in2 = GetRandHash(); + uint256 in2 = InsecureRand256(); uint256 res3; // Check that we can write successfully diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp index 9f59de3ef5..01cc5ed831 100644 --- a/src/test/getarg_tests.cpp +++ b/src/test/getarg_tests.cpp @@ -25,7 +25,7 @@ static void ResetArgs(const std::string& strArg) // Convert to char*: std::vector<const char*> vecChar; - BOOST_FOREACH(std::string& s, vecArg) + for (std::string& s : vecArg) vecChar.push_back(s.c_str()); ParseParameters(vecChar.size(), &vecChar[0]); diff --git a/src/test/hash_tests.cpp b/src/test/hash_tests.cpp index d8de765db1..05b6b3b1e6 100644 --- a/src/test/hash_tests.cpp +++ b/src/test/hash_tests.cpp @@ -128,6 +128,23 @@ BOOST_AUTO_TEST_CASE(siphash) tx.nVersion = 1; ss << tx; BOOST_CHECK_EQUAL(SipHashUint256(1, 2, ss.GetHash()), 0x79751e980c2a0a35ULL); + + // Check consistency between CSipHasher and SipHashUint256[Extra]. + FastRandomContext ctx; + for (int i = 0; i < 16; ++i) { + uint64_t k1 = ctx.rand64(); + uint64_t k2 = ctx.rand64(); + uint256 x = InsecureRand256(); + uint32_t n = ctx.rand32(); + uint8_t nb[4]; + WriteLE32(nb, n); + CSipHasher sip256(k1, k2); + sip256.Write(x.begin(), 32); + CSipHasher sip288 = sip256; + sip288.Write(nb, 4); + BOOST_CHECK_EQUAL(SipHashUint256(k1, k2, x), sip256.Finalize()); + BOOST_CHECK_EQUAL(SipHashUint256Extra(k1, k2, x, n), sip288.Finalize()); + } } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/main_tests.cpp b/src/test/main_tests.cpp index d52104b4cc..656aec606b 100644 --- a/src/test/main_tests.cpp +++ b/src/test/main_tests.cpp @@ -39,17 +39,18 @@ static void TestBlockSubsidyHalvings(int nSubsidyHalvingInterval) BOOST_AUTO_TEST_CASE(block_subsidy_test) { - TestBlockSubsidyHalvings(Params(CBaseChainParams::MAIN).GetConsensus()); // As in main + const auto chainParams = CreateChainParams(CBaseChainParams::MAIN); + TestBlockSubsidyHalvings(chainParams->GetConsensus()); // As in main TestBlockSubsidyHalvings(150); // As in regtest TestBlockSubsidyHalvings(1000); // Just another interval } BOOST_AUTO_TEST_CASE(subsidy_limit_test) { - const Consensus::Params& consensusParams = Params(CBaseChainParams::MAIN).GetConsensus(); + const auto chainParams = CreateChainParams(CBaseChainParams::MAIN); CAmount nSum = 0; for (int nHeight = 0; nHeight < 14000000; nHeight += 1000) { - CAmount nSubsidy = GetBlockSubsidy(nHeight, consensusParams); + CAmount nSubsidy = GetBlockSubsidy(nHeight, chainParams->GetConsensus()); BOOST_CHECK(nSubsidy <= 50 * COIN); nSum += nSubsidy * 1000; BOOST_CHECK(MoneyRange(nSum)); diff --git a/src/test/merkle_tests.cpp b/src/test/merkle_tests.cpp index f2f06fa8e2..1a1cf4399c 100644 --- a/src/test/merkle_tests.cpp +++ b/src/test/merkle_tests.cpp @@ -4,7 +4,6 @@ #include "consensus/merkle.h" #include "test/test_bitcoin.h" -#include "test/test_random.h" #include <boost/test/unit_test.hpp> @@ -68,7 +67,7 @@ BOOST_AUTO_TEST_CASE(merkle_test) { for (int i = 0; i < 32; i++) { // Try 32 block sizes: all sizes from 0 to 16 inclusive, and then 15 random sizes. - int ntx = (i <= 16) ? i : 17 + (insecure_rand() % 4000); + int ntx = (i <= 16) ? i : 17 + (InsecureRandRange(4000)); // Try up to 3 mutations. for (int mutate = 0; mutate <= 3; mutate++) { int duplicate1 = mutate >= 1 ? 1 << ctz(ntx) : 0; // The last how many transactions to duplicate first. @@ -121,7 +120,7 @@ BOOST_AUTO_TEST_CASE(merkle_test) // If ntx <= 16, try all branches. Otherwise, try 16 random ones. int mtx = loop; if (ntx > 16) { - mtx = insecure_rand() % ntx; + mtx = InsecureRandRange(ntx); } std::vector<uint256> newBranch = BlockMerkleBranch(block, mtx); std::vector<uint256> oldBranch = BlockGetMerkleBranch(block, merkleTree, mtx); diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 41f42c7b88..eaff2ac70d 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -6,6 +6,7 @@ #include "coins.h" #include "consensus/consensus.h" #include "consensus/merkle.h" +#include "consensus/tx_verify.h" #include "consensus/validation.h" #include "validation.h" #include "miner.h" @@ -194,7 +195,8 @@ void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) { // Note that by default, these tests run with size accounting enabled. - const CChainParams& chainparams = Params(CBaseChainParams::MAIN); + const auto chainParams = CreateChainParams(CBaseChainParams::MAIN); + const CChainParams& chainparams = *chainParams; CScript scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; std::unique_ptr<CBlockTemplate> pblocktemplate; CMutableTransaction tx,tx2; @@ -258,7 +260,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) { tx.vout[0].nValue -= LOWFEE; hash = tx.GetHash(); - bool spendsCoinbase = (i == 0) ? true : false; // only first tx spends coinbase + bool spendsCoinbase = i == 0; // only first tx spends coinbase // If we don't set the # of sig ops in the CTxMemPoolEntry, template creation fails mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); tx.vin[0].prevout.hash = hash; @@ -272,7 +274,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) { tx.vout[0].nValue -= LOWFEE; hash = tx.GetHash(); - bool spendsCoinbase = (i == 0) ? true : false; // only first tx spends coinbase + bool spendsCoinbase = i == 0; // only first tx spends coinbase // If we do set the # of sig ops in the CTxMemPoolEntry, template creation passes mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).SigOpsCost(80).FromTx(tx)); tx.vin[0].prevout.hash = hash; @@ -293,7 +295,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) { tx.vout[0].nValue -= LOWFEE; hash = tx.GetHash(); - bool spendsCoinbase = (i == 0) ? true : false; // only first tx spends coinbase + bool spendsCoinbase = i == 0; // only first tx spends coinbase mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); tx.vin[0].prevout.hash = hash; } @@ -370,7 +372,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) while (chainActive.Tip()->nHeight < 209999) { CBlockIndex* prev = chainActive.Tip(); CBlockIndex* next = new CBlockIndex(); - next->phashBlock = new uint256(GetRandHash()); + next->phashBlock = new uint256(InsecureRand256()); pcoinsTip->SetBestBlock(next->GetBlockHash()); next->pprev = prev; next->nHeight = prev->nHeight + 1; @@ -382,7 +384,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) while (chainActive.Tip()->nHeight < 210000) { CBlockIndex* prev = chainActive.Tip(); CBlockIndex* next = new CBlockIndex(); - next->phashBlock = new uint256(GetRandHash()); + next->phashBlock = new uint256(InsecureRand256()); pcoinsTip->SetBestBlock(next->GetBlockHash()); next->pprev = prev; next->nHeight = prev->nHeight + 1; diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp index dd5678ea6e..6d8aab887b 100644 --- a/src/test/multisig_tests.cpp +++ b/src/test/multisig_tests.cpp @@ -28,7 +28,7 @@ sign_multisig(CScript scriptPubKey, std::vector<CKey> keys, CTransaction transac CScript result; result << OP_0; // CHECKMULTISIG bug workaround - BOOST_FOREACH(const CKey &key, keys) + for (const CKey &key : keys) { std::vector<unsigned char> vchSig; BOOST_CHECK(key.Sign(hash, vchSig)); diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index 0c7f3e5e23..66354699b2 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -175,12 +175,12 @@ BOOST_AUTO_TEST_CASE(cnode_simple_test) bool fInboundIn = false; // Test that fFeeler is false by default. - std::unique_ptr<CNode> pnode1(new CNode(id++, NODE_NETWORK, height, hSocket, addr, 0, 0, pszDest, fInboundIn)); + std::unique_ptr<CNode> pnode1(new CNode(id++, NODE_NETWORK, height, hSocket, addr, 0, 0, CAddress(), pszDest, fInboundIn)); BOOST_CHECK(pnode1->fInbound == false); BOOST_CHECK(pnode1->fFeeler == false); fInboundIn = true; - std::unique_ptr<CNode> pnode2(new CNode(id++, NODE_NETWORK, height, hSocket, addr, 1, 1, pszDest, fInboundIn)); + std::unique_ptr<CNode> pnode2(new CNode(id++, NODE_NETWORK, height, hSocket, addr, 1, 1, CAddress(), pszDest, fInboundIn)); BOOST_CHECK(pnode2->fInbound == true); BOOST_CHECK(pnode2->fFeeler == false); } diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index 1afef5b1ce..b45a7fcc57 100644 --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -7,7 +7,6 @@ #include <string> -#include <boost/assign/list_of.hpp> #include <boost/test/unit_test.hpp> BOOST_FIXTURE_TEST_SUITE(netbase_tests, BasicTestingSetup) @@ -26,6 +25,13 @@ static CSubNet ResolveSubNet(const char* subnet) return ret; } +static CNetAddr CreateInternal(const char* host) +{ + CNetAddr addr; + addr.SetInternal(host); + return addr; +} + BOOST_AUTO_TEST_CASE(netbase_networks) { BOOST_CHECK(ResolveIP("127.0.0.1").GetNetwork() == NET_UNROUTABLE); @@ -33,6 +39,7 @@ BOOST_AUTO_TEST_CASE(netbase_networks) BOOST_CHECK(ResolveIP("8.8.8.8").GetNetwork() == NET_IPV4); BOOST_CHECK(ResolveIP("2001::8888").GetNetwork() == NET_IPV6); BOOST_CHECK(ResolveIP("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").GetNetwork() == NET_TOR); + BOOST_CHECK(CreateInternal("foo.com").GetNetwork() == NET_INTERNAL); } @@ -59,6 +66,8 @@ BOOST_AUTO_TEST_CASE(netbase_properties) BOOST_CHECK(ResolveIP("8.8.8.8").IsRoutable()); BOOST_CHECK(ResolveIP("2001::1").IsRoutable()); BOOST_CHECK(ResolveIP("127.0.0.1").IsValid()); + BOOST_CHECK(CreateInternal("FD6B:88C0:8724:edb1:8e4:3588:e546:35ca").IsInternal()); + BOOST_CHECK(CreateInternal("bar.com").IsInternal()); } @@ -104,6 +113,11 @@ BOOST_AUTO_TEST_CASE(netbase_lookupnumeric) BOOST_CHECK(TestParse("[::]:8333", "[::]:8333")); BOOST_CHECK(TestParse("[127.0.0.1]", "127.0.0.1:65535")); BOOST_CHECK(TestParse(":::", "[::]:0")); + + // verify that an internal address fails to resolve + BOOST_CHECK(TestParse("[fd6b:88c0:8724:1:2:3:4:5]", "[::]:0")); + // and that a one-off resolves correctly + BOOST_CHECK(TestParse("[fd6c:88c0:8724:1:2:3:4:5]", "[fd6c:88c0:8724:1:2:3:4:5]:65535")); } BOOST_AUTO_TEST_CASE(onioncat_test) @@ -269,19 +283,22 @@ BOOST_AUTO_TEST_CASE(subnet_test) BOOST_AUTO_TEST_CASE(netbase_getgroup) { - BOOST_CHECK(ResolveIP("127.0.0.1").GetGroup() == boost::assign::list_of(0)); // Local -> !Routable() - BOOST_CHECK(ResolveIP("257.0.0.1").GetGroup() == boost::assign::list_of(0)); // !Valid -> !Routable() - BOOST_CHECK(ResolveIP("10.0.0.1").GetGroup() == boost::assign::list_of(0)); // RFC1918 -> !Routable() - BOOST_CHECK(ResolveIP("169.254.1.1").GetGroup() == boost::assign::list_of(0)); // RFC3927 -> !Routable() - BOOST_CHECK(ResolveIP("1.2.3.4").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // IPv4 - BOOST_CHECK(ResolveIP("::FFFF:0:102:304").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC6145 - BOOST_CHECK(ResolveIP("64:FF9B::102:304").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC6052 - BOOST_CHECK(ResolveIP("2002:102:304:9999:9999:9999:9999:9999").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC3964 - BOOST_CHECK(ResolveIP("2001:0:9999:9999:9999:9999:FEFD:FCFB").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC4380 - BOOST_CHECK(ResolveIP("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").GetGroup() == boost::assign::list_of((unsigned char)NET_TOR)(239)); // Tor - BOOST_CHECK(ResolveIP("2001:470:abcd:9999:9999:9999:9999:9999").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV6)(32)(1)(4)(112)(175)); //he.net - BOOST_CHECK(ResolveIP("2001:2001:9999:9999:9999:9999:9999:9999").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV6)(32)(1)(32)(1)); //IPv6 + BOOST_CHECK(ResolveIP("127.0.0.1").GetGroup() == std::vector<unsigned char>({0})); // Local -> !Routable() + BOOST_CHECK(ResolveIP("257.0.0.1").GetGroup() == std::vector<unsigned char>({0})); // !Valid -> !Routable() + BOOST_CHECK(ResolveIP("10.0.0.1").GetGroup() == std::vector<unsigned char>({0})); // RFC1918 -> !Routable() + BOOST_CHECK(ResolveIP("169.254.1.1").GetGroup() == std::vector<unsigned char>({0})); // RFC3927 -> !Routable() + BOOST_CHECK(ResolveIP("1.2.3.4").GetGroup() == std::vector<unsigned char>({(unsigned char)NET_IPV4, 1, 2})); // IPv4 + BOOST_CHECK(ResolveIP("::FFFF:0:102:304").GetGroup() == std::vector<unsigned char>({(unsigned char)NET_IPV4, 1, 2})); // RFC6145 + BOOST_CHECK(ResolveIP("64:FF9B::102:304").GetGroup() == std::vector<unsigned char>({(unsigned char)NET_IPV4, 1, 2})); // RFC6052 + BOOST_CHECK(ResolveIP("2002:102:304:9999:9999:9999:9999:9999").GetGroup() == std::vector<unsigned char>({(unsigned char)NET_IPV4, 1, 2})); // RFC3964 + BOOST_CHECK(ResolveIP("2001:0:9999:9999:9999:9999:FEFD:FCFB").GetGroup() == std::vector<unsigned char>({(unsigned char)NET_IPV4, 1, 2})); // RFC4380 + BOOST_CHECK(ResolveIP("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").GetGroup() == std::vector<unsigned char>({(unsigned char)NET_TOR, 239})); // Tor + BOOST_CHECK(ResolveIP("2001:470:abcd:9999:9999:9999:9999:9999").GetGroup() == std::vector<unsigned char>({(unsigned char)NET_IPV6, 32, 1, 4, 112, 175})); //he.net + BOOST_CHECK(ResolveIP("2001:2001:9999:9999:9999:9999:9999:9999").GetGroup() == std::vector<unsigned char>({(unsigned char)NET_IPV6, 32, 1, 32, 1})); //IPv6 + // baz.net sha256 hash: 12929400eb4607c4ac075f087167e75286b179c693eb059a01774b864e8fe505 + std::vector<unsigned char> internal_group = {NET_INTERNAL, 0x12, 0x92, 0x94, 0x00, 0xeb, 0x46, 0x07, 0xc4, 0xac, 0x07}; + BOOST_CHECK(CreateInternal("baz.net").GetGroup() == internal_group); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp index a1cb32019a..c1d216d094 100644 --- a/src/test/pmt_tests.cpp +++ b/src/test/pmt_tests.cpp @@ -10,11 +10,9 @@ #include "arith_uint256.h" #include "version.h" #include "test/test_bitcoin.h" -#include "test/test_random.h" #include <vector> -#include <boost/assign/list_of.hpp> #include <boost/test/unit_test.hpp> class CPartialMerkleTreeTester : public CPartialMerkleTree @@ -22,8 +20,8 @@ class CPartialMerkleTreeTester : public CPartialMerkleTree public: // flip one bit in one of the hashes - this should break the authentication void Damage() { - unsigned int n = insecure_rand() % vHash.size(); - int bit = insecure_rand() % 256; + unsigned int n = InsecureRandRange(vHash.size()); + int bit = InsecureRandBits(8); *(vHash[n].begin() + (bit>>3)) ^= 1<<(bit&7); } }; @@ -32,7 +30,7 @@ BOOST_FIXTURE_TEST_SUITE(pmt_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(pmt_test1) { - seed_insecure_rand(false); + SeedInsecureRand(false); static const unsigned int nTxCounts[] = {1, 4, 7, 17, 56, 100, 127, 256, 312, 513, 1000, 4095}; for (int i = 0; i < 12; i++) { @@ -63,7 +61,7 @@ BOOST_AUTO_TEST_CASE(pmt_test1) std::vector<bool> vMatch(nTx, false); std::vector<uint256> vMatchTxid1; for (unsigned int j=0; j<nTx; j++) { - bool fInclude = (insecure_rand() & ((1 << (att/2)) - 1)) == 0; + bool fInclude = InsecureRandBits(att / 2) == 0; vMatch[j] = fInclude; if (fInclude) vMatchTxid1.push_back(vTxid[j]); @@ -110,14 +108,15 @@ BOOST_AUTO_TEST_CASE(pmt_test1) BOOST_AUTO_TEST_CASE(pmt_malleability) { - std::vector<uint256> vTxid = boost::assign::list_of - (ArithToUint256(1))(ArithToUint256(2)) - (ArithToUint256(3))(ArithToUint256(4)) - (ArithToUint256(5))(ArithToUint256(6)) - (ArithToUint256(7))(ArithToUint256(8)) - (ArithToUint256(9))(ArithToUint256(10)) - (ArithToUint256(9))(ArithToUint256(10)); - std::vector<bool> vMatch = boost::assign::list_of(false)(false)(false)(false)(false)(false)(false)(false)(false)(true)(true)(false); + std::vector<uint256> vTxid = { + ArithToUint256(1), ArithToUint256(2), + ArithToUint256(3), ArithToUint256(4), + ArithToUint256(5), ArithToUint256(6), + ArithToUint256(7), ArithToUint256(8), + ArithToUint256(9), ArithToUint256(10), + ArithToUint256(9), ArithToUint256(10), + }; + std::vector<bool> vMatch = {false, false, false, false, false, false, false, false, false, true, true, false}; CPartialMerkleTree tree(vTxid, vMatch); std::vector<unsigned int> vIndex; diff --git a/src/test/policyestimator_tests.cpp b/src/test/policyestimator_tests.cpp index ed6782ea34..6bfd315647 100644 --- a/src/test/policyestimator_tests.cpp +++ b/src/test/policyestimator_tests.cpp @@ -50,8 +50,8 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) int blocknum = 0; // Loop through 200 blocks - // At a decay .998 and 4 fee transactions per block - // This makes the tx count about 1.33 per bucket, above the 1 threshold + // At a decay .9952 and 4 fee transactions per block + // This makes the tx count about 2.5 per bucket, well above the 0.1 threshold while (blocknum < 200) { for (int j = 0; j < 10; j++) { // For each fee for (int k = 0; k < 4; k++) { // add 4 fee txs @@ -75,20 +75,14 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) } mpool.removeForBlock(block, ++blocknum); block.clear(); - if (blocknum == 30) { - // At this point we should need to combine 5 buckets to get enough data points - // So estimateFee(1,2,3) should fail and estimateFee(4) should return somewhere around - // 8*baserate. estimateFee(4) %'s are 100,100,100,100,90 = average 98% + // Check after just a few txs that combining buckets works as expected + if (blocknum == 3) { + // At this point we should need to combine 3 buckets to get enough data points + // So estimateFee(1) should fail and estimateFee(2) should return somewhere around + // 9*baserate. estimateFee(2) %'s are 100,100,90 = average 97% BOOST_CHECK(feeEst.estimateFee(1) == CFeeRate(0)); - BOOST_CHECK(feeEst.estimateFee(2) == CFeeRate(0)); - BOOST_CHECK(feeEst.estimateFee(3) == CFeeRate(0)); - BOOST_CHECK(feeEst.estimateFee(4).GetFeePerK() < 8*baseRate.GetFeePerK() + deltaFee); - BOOST_CHECK(feeEst.estimateFee(4).GetFeePerK() > 8*baseRate.GetFeePerK() - deltaFee); - int answerFound; - BOOST_CHECK(feeEst.estimateSmartFee(1, &answerFound, mpool) == feeEst.estimateFee(4) && answerFound == 4); - BOOST_CHECK(feeEst.estimateSmartFee(3, &answerFound, mpool) == feeEst.estimateFee(4) && answerFound == 4); - BOOST_CHECK(feeEst.estimateSmartFee(4, &answerFound, mpool) == feeEst.estimateFee(4) && answerFound == 4); - BOOST_CHECK(feeEst.estimateSmartFee(8, &answerFound, mpool) == feeEst.estimateFee(8) && answerFound == 8); + BOOST_CHECK(feeEst.estimateFee(2).GetFeePerK() < 9*baseRate.GetFeePerK() + deltaFee); + BOOST_CHECK(feeEst.estimateFee(2).GetFeePerK() > 9*baseRate.GetFeePerK() - deltaFee); } } @@ -105,13 +99,14 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) BOOST_CHECK(origFeeEst[i-1] <= origFeeEst[i-2]); } int mult = 11-i; - if (i > 1) { + if (i % 2 == 0) { //At scale 2, test logic is only correct for even targets BOOST_CHECK(origFeeEst[i-1] < mult*baseRate.GetFeePerK() + deltaFee); BOOST_CHECK(origFeeEst[i-1] > mult*baseRate.GetFeePerK() - deltaFee); } - else { - BOOST_CHECK(origFeeEst[i-1] == CFeeRate(0).GetFeePerK()); - } + } + // Fill out rest of the original estimates + for (int i = 10; i <= 48; i++) { + origFeeEst.push_back(feeEst.estimateFee(i).GetFeePerK()); } // Mine 50 more blocks with no transactions happening, estimates shouldn't change @@ -140,10 +135,8 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) mpool.removeForBlock(block, ++blocknum); } - int answerFound; for (int i = 1; i < 10;i++) { BOOST_CHECK(feeEst.estimateFee(i) == CFeeRate(0) || feeEst.estimateFee(i).GetFeePerK() > origFeeEst[i-1] - deltaFee); - BOOST_CHECK(feeEst.estimateSmartFee(i, &answerFound, mpool).GetFeePerK() > origFeeEst[answerFound-1] - deltaFee); } // Mine all those transactions @@ -156,16 +149,16 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) txHashes[j].pop_back(); } } - mpool.removeForBlock(block, 265); + mpool.removeForBlock(block, 266); block.clear(); BOOST_CHECK(feeEst.estimateFee(1) == CFeeRate(0)); for (int i = 2; i < 10;i++) { - BOOST_CHECK(feeEst.estimateFee(i).GetFeePerK() > origFeeEst[i-1] - deltaFee); + BOOST_CHECK(feeEst.estimateFee(i) == CFeeRate(0) || feeEst.estimateFee(i).GetFeePerK() > origFeeEst[i-1] - deltaFee); } - // Mine 200 more blocks where everything is mined every block + // Mine 400 more blocks where everything is mined every block // Estimates should be below original estimates - while (blocknum < 465) { + while (blocknum < 665) { for (int j = 0; j < 10; j++) { // For each fee multiple for (int k = 0; k < 4; k++) { // add 4 fee txs tx.vin[0].prevout.n = 10000*blocknum+100*j+k; @@ -181,7 +174,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) block.clear(); } BOOST_CHECK(feeEst.estimateFee(1) == CFeeRate(0)); - for (int i = 2; i < 10; i++) { + for (int i = 2; i < 9; i++) { // At 9, the original estimate was already at the bottom (b/c scale = 2) BOOST_CHECK(feeEst.estimateFee(i).GetFeePerK() < origFeeEst[i-1] - deltaFee); } @@ -191,7 +184,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) mpool.TrimToSize(1); BOOST_CHECK(mpool.GetMinFee(1).GetFeePerK() > feeV[5]); for (int i = 1; i < 10; i++) { - BOOST_CHECK(feeEst.estimateSmartFee(i, NULL, mpool).GetFeePerK() >= feeEst.estimateFee(i).GetFeePerK()); + BOOST_CHECK(feeEst.estimateSmartFee(i, NULL, mpool).GetFeePerK() >= feeEst.estimateRawFee(i, 0.85, FeeEstimateHorizon::MED_HALFLIFE).GetFeePerK()); BOOST_CHECK(feeEst.estimateSmartFee(i, NULL, mpool).GetFeePerK() >= mpool.GetMinFee(1).GetFeePerK()); } } diff --git a/src/test/pow_tests.cpp b/src/test/pow_tests.cpp index 4ca6f1caf0..b9fabd02e4 100644 --- a/src/test/pow_tests.cpp +++ b/src/test/pow_tests.cpp @@ -16,79 +16,69 @@ BOOST_FIXTURE_TEST_SUITE(pow_tests, BasicTestingSetup) /* Test calculation of next difficulty target with no constraints applying */ BOOST_AUTO_TEST_CASE(get_next_work) { - SelectParams(CBaseChainParams::MAIN); - const Consensus::Params& params = Params().GetConsensus(); - + const auto chainParams = CreateChainParams(CBaseChainParams::MAIN); int64_t nLastRetargetTime = 1261130161; // Block #30240 CBlockIndex pindexLast; pindexLast.nHeight = 32255; pindexLast.nTime = 1262152739; // Block #32255 pindexLast.nBits = 0x1d00ffff; - BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, params), 0x1d00d86a); + BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1d00d86a); } /* Test the constraint on the upper bound for next work */ BOOST_AUTO_TEST_CASE(get_next_work_pow_limit) { - SelectParams(CBaseChainParams::MAIN); - const Consensus::Params& params = Params().GetConsensus(); - + const auto chainParams = CreateChainParams(CBaseChainParams::MAIN); int64_t nLastRetargetTime = 1231006505; // Block #0 CBlockIndex pindexLast; pindexLast.nHeight = 2015; pindexLast.nTime = 1233061996; // Block #2015 pindexLast.nBits = 0x1d00ffff; - BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, params), 0x1d00ffff); + BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1d00ffff); } /* Test the constraint on the lower bound for actual time taken */ BOOST_AUTO_TEST_CASE(get_next_work_lower_limit_actual) { - SelectParams(CBaseChainParams::MAIN); - const Consensus::Params& params = Params().GetConsensus(); - + const auto chainParams = CreateChainParams(CBaseChainParams::MAIN); int64_t nLastRetargetTime = 1279008237; // Block #66528 CBlockIndex pindexLast; pindexLast.nHeight = 68543; pindexLast.nTime = 1279297671; // Block #68543 pindexLast.nBits = 0x1c05a3f4; - BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, params), 0x1c0168fd); + BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1c0168fd); } /* Test the constraint on the upper bound for actual time taken */ BOOST_AUTO_TEST_CASE(get_next_work_upper_limit_actual) { - SelectParams(CBaseChainParams::MAIN); - const Consensus::Params& params = Params().GetConsensus(); - + const auto chainParams = CreateChainParams(CBaseChainParams::MAIN); int64_t nLastRetargetTime = 1263163443; // NOTE: Not an actual block time CBlockIndex pindexLast; pindexLast.nHeight = 46367; pindexLast.nTime = 1269211443; // Block #46367 pindexLast.nBits = 0x1c387f6f; - BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, params), 0x1d00e1fd); + BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1d00e1fd); } BOOST_AUTO_TEST_CASE(GetBlockProofEquivalentTime_test) { - SelectParams(CBaseChainParams::MAIN); - const Consensus::Params& params = Params().GetConsensus(); - + const auto chainParams = CreateChainParams(CBaseChainParams::MAIN); std::vector<CBlockIndex> blocks(10000); for (int i = 0; i < 10000; i++) { blocks[i].pprev = i ? &blocks[i - 1] : NULL; blocks[i].nHeight = i; - blocks[i].nTime = 1269211443 + i * params.nPowTargetSpacing; + blocks[i].nTime = 1269211443 + i * chainParams->GetConsensus().nPowTargetSpacing; blocks[i].nBits = 0x207fffff; /* target 0x7fffff000... */ blocks[i].nChainWork = i ? blocks[i - 1].nChainWork + GetBlockProof(blocks[i - 1]) : arith_uint256(0); } for (int j = 0; j < 1000; j++) { - CBlockIndex *p1 = &blocks[GetRand(10000)]; - CBlockIndex *p2 = &blocks[GetRand(10000)]; - CBlockIndex *p3 = &blocks[GetRand(10000)]; + CBlockIndex *p1 = &blocks[InsecureRandRange(10000)]; + CBlockIndex *p2 = &blocks[InsecureRandRange(10000)]; + CBlockIndex *p3 = &blocks[InsecureRandRange(10000)]; - int64_t tdiff = GetBlockProofEquivalentTime(*p1, *p2, *p3, params); + int64_t tdiff = GetBlockProofEquivalentTime(*p1, *p2, *p3, chainParams->GetConsensus()); BOOST_CHECK_EQUAL(tdiff, p1->GetBlockTime() - p2->GetBlockTime()); } } diff --git a/src/test/prevector_tests.cpp b/src/test/prevector_tests.cpp index cfed5e347e..11bb11d1e9 100644 --- a/src/test/prevector_tests.cpp +++ b/src/test/prevector_tests.cpp @@ -9,7 +9,6 @@ #include "streams.h" #include "test/test_bitcoin.h" -#include "test/test_random.h" #include <boost/test/unit_test.hpp> @@ -54,13 +53,13 @@ class prevector_tester { local_check(pretype(real_vector.begin(), real_vector.end()) == pre_vector); local_check(pretype(pre_vector.begin(), pre_vector.end()) == pre_vector); size_t pos = 0; - BOOST_FOREACH(const T& v, pre_vector) { + for (const T& v : pre_vector) { local_check(v == real_vector[pos++]); } BOOST_REVERSE_FOREACH(const T& v, pre_vector) { local_check(v == real_vector[--pos]); } - BOOST_FOREACH(const T& v, const_pre_vector) { + for (const T& v : const_pre_vector) { local_check(v == real_vector[pos++]); } BOOST_REVERSE_FOREACH(const T& v, const_pre_vector) { @@ -188,7 +187,7 @@ public: } prevector_tester() { - seed_insecure_rand(); + SeedInsecureRand(); rand_seed = insecure_rand_seed; rand_cache = insecure_rand_ctx; } @@ -199,67 +198,65 @@ BOOST_AUTO_TEST_CASE(PrevectorTestInt) for (int j = 0; j < 64; j++) { prevector_tester<8, int> test; for (int i = 0; i < 2048; i++) { - int r = insecure_rand(); - if ((r % 4) == 0) { - test.insert(insecure_rand() % (test.size() + 1), insecure_rand()); + if (InsecureRandBits(2) == 0) { + test.insert(InsecureRandRange(test.size() + 1), InsecureRand32()); } - if (test.size() > 0 && ((r >> 2) % 4) == 1) { - test.erase(insecure_rand() % test.size()); + if (test.size() > 0 && InsecureRandBits(2) == 1) { + test.erase(InsecureRandRange(test.size())); } - if (((r >> 4) % 8) == 2) { - int new_size = std::max<int>(0, std::min<int>(30, test.size() + (insecure_rand() % 5) - 2)); + if (InsecureRandBits(3) == 2) { + int new_size = std::max<int>(0, std::min<int>(30, test.size() + (InsecureRandRange(5)) - 2)); test.resize(new_size); } - if (((r >> 7) % 8) == 3) { - test.insert(insecure_rand() % (test.size() + 1), 1 + (insecure_rand() % 2), insecure_rand()); + if (InsecureRandBits(3) == 3) { + test.insert(InsecureRandRange(test.size() + 1), 1 + InsecureRandBool(), InsecureRand32()); } - if (((r >> 10) % 8) == 4) { - int del = std::min<int>(test.size(), 1 + (insecure_rand() % 2)); - int beg = insecure_rand() % (test.size() + 1 - del); + if (InsecureRandBits(3) == 4) { + int del = std::min<int>(test.size(), 1 + (InsecureRandBool())); + int beg = InsecureRandRange(test.size() + 1 - del); test.erase(beg, beg + del); } - if (((r >> 13) % 16) == 5) { - test.push_back(insecure_rand()); + if (InsecureRandBits(4) == 5) { + test.push_back(InsecureRand32()); } - if (test.size() > 0 && ((r >> 17) % 16) == 6) { + if (test.size() > 0 && InsecureRandBits(4) == 6) { test.pop_back(); } - if (((r >> 21) % 32) == 7) { + if (InsecureRandBits(5) == 7) { int values[4]; - int num = 1 + (insecure_rand() % 4); + int num = 1 + (InsecureRandBits(2)); for (int k = 0; k < num; k++) { - values[k] = insecure_rand(); + values[k] = InsecureRand32(); } - test.insert_range(insecure_rand() % (test.size() + 1), values, values + num); + test.insert_range(InsecureRandRange(test.size() + 1), values, values + num); } - if (((r >> 26) % 32) == 8) { - int del = std::min<int>(test.size(), 1 + (insecure_rand() % 4)); - int beg = insecure_rand() % (test.size() + 1 - del); + if (InsecureRandBits(5) == 8) { + int del = std::min<int>(test.size(), 1 + (InsecureRandBits(2))); + int beg = InsecureRandRange(test.size() + 1 - del); test.erase(beg, beg + del); } - r = insecure_rand(); - if (r % 32 == 9) { - test.reserve(insecure_rand() % 32); + if (InsecureRandBits(5) == 9) { + test.reserve(InsecureRandBits(5)); } - if ((r >> 5) % 64 == 10) { + if (InsecureRandBits(6) == 10) { test.shrink_to_fit(); } if (test.size() > 0) { - test.update(insecure_rand() % test.size(), insecure_rand()); + test.update(InsecureRandRange(test.size()), InsecureRand32()); } - if (((r >> 11) % 1024) == 11) { + if (InsecureRandBits(10) == 11) { test.clear(); } - if (((r >> 21) % 512) == 12) { - test.assign(insecure_rand() % 32, insecure_rand()); + if (InsecureRandBits(9) == 12) { + test.assign(InsecureRandBits(5), InsecureRand32()); } - if (((r >> 15) % 8) == 3) { + if (InsecureRandBits(3) == 3) { test.swap(); } - if (((r >> 15) % 16) == 8) { + if (InsecureRandBits(4) == 8) { test.copy(); } - if (((r >> 15) % 32) == 18) { + if (InsecureRandBits(5) == 18) { test.move(); } } diff --git a/src/test/random_tests.cpp b/src/test/random_tests.cpp index 8596734226..132e190051 100644 --- a/src/test/random_tests.cpp +++ b/src/test/random_tests.cpp @@ -25,14 +25,21 @@ BOOST_AUTO_TEST_CASE(fastrandom_tests) BOOST_CHECK_EQUAL(ctx1.rand32(), ctx2.rand32()); BOOST_CHECK_EQUAL(ctx1.rand64(), ctx2.rand64()); BOOST_CHECK_EQUAL(ctx1.randbits(3), ctx2.randbits(3)); + BOOST_CHECK(ctx1.randbytes(17) == ctx2.randbytes(17)); + BOOST_CHECK(ctx1.rand256() == ctx2.rand256()); BOOST_CHECK_EQUAL(ctx1.randbits(7), ctx2.randbits(7)); + BOOST_CHECK(ctx1.randbytes(128) == ctx2.randbytes(128)); BOOST_CHECK_EQUAL(ctx1.rand32(), ctx2.rand32()); BOOST_CHECK_EQUAL(ctx1.randbits(3), ctx2.randbits(3)); + BOOST_CHECK(ctx1.rand256() == ctx2.rand256()); + BOOST_CHECK(ctx1.randbytes(50) == ctx2.randbytes(50)); // Check that a nondeterministic ones are not FastRandomContext ctx3; FastRandomContext ctx4; BOOST_CHECK(ctx3.rand64() != ctx4.rand64()); // extremely unlikely to be equal + BOOST_CHECK(ctx3.rand256() != ctx4.rand256()); + BOOST_CHECK(ctx3.randbytes(7) != ctx4.randbytes(7)); } BOOST_AUTO_TEST_CASE(fastrandom_randbits) diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 7cf2a744ea..134bd7c609 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -11,7 +11,6 @@ #include "test/test_bitcoin.h" #include <boost/algorithm/string.hpp> -#include <boost/assign/list_of.hpp> #include <boost/test/unit_test.hpp> #include <univalue.h> @@ -324,20 +323,20 @@ BOOST_AUTO_TEST_CASE(rpc_convert_values_generatetoaddress) { UniValue result; - BOOST_CHECK_NO_THROW(result = RPCConvertValues("generatetoaddress", boost::assign::list_of("101")("mkESjLZW66TmHhiFX8MCaBjrhZ543PPh9a"))); + BOOST_CHECK_NO_THROW(result = RPCConvertValues("generatetoaddress", {"101", "mkESjLZW66TmHhiFX8MCaBjrhZ543PPh9a"})); BOOST_CHECK_EQUAL(result[0].get_int(), 101); BOOST_CHECK_EQUAL(result[1].get_str(), "mkESjLZW66TmHhiFX8MCaBjrhZ543PPh9a"); - BOOST_CHECK_NO_THROW(result = RPCConvertValues("generatetoaddress", boost::assign::list_of("101")("mhMbmE2tE9xzJYCV9aNC8jKWN31vtGrguU"))); + BOOST_CHECK_NO_THROW(result = RPCConvertValues("generatetoaddress", {"101", "mhMbmE2tE9xzJYCV9aNC8jKWN31vtGrguU"})); BOOST_CHECK_EQUAL(result[0].get_int(), 101); BOOST_CHECK_EQUAL(result[1].get_str(), "mhMbmE2tE9xzJYCV9aNC8jKWN31vtGrguU"); - BOOST_CHECK_NO_THROW(result = RPCConvertValues("generatetoaddress", boost::assign::list_of("1")("mkESjLZW66TmHhiFX8MCaBjrhZ543PPh9a")("9"))); + BOOST_CHECK_NO_THROW(result = RPCConvertValues("generatetoaddress", {"1", "mkESjLZW66TmHhiFX8MCaBjrhZ543PPh9a", "9"})); BOOST_CHECK_EQUAL(result[0].get_int(), 1); BOOST_CHECK_EQUAL(result[1].get_str(), "mkESjLZW66TmHhiFX8MCaBjrhZ543PPh9a"); BOOST_CHECK_EQUAL(result[2].get_int(), 9); - BOOST_CHECK_NO_THROW(result = RPCConvertValues("generatetoaddress", boost::assign::list_of("1")("mhMbmE2tE9xzJYCV9aNC8jKWN31vtGrguU")("9"))); + BOOST_CHECK_NO_THROW(result = RPCConvertValues("generatetoaddress", {"1", "mhMbmE2tE9xzJYCV9aNC8jKWN31vtGrguU", "9"})); BOOST_CHECK_EQUAL(result[0].get_int(), 1); BOOST_CHECK_EQUAL(result[1].get_str(), "mhMbmE2tE9xzJYCV9aNC8jKWN31vtGrguU"); BOOST_CHECK_EQUAL(result[2].get_int(), 9); diff --git a/src/test/scheduler_tests.cpp b/src/test/scheduler_tests.cpp index e4ddf9d618..1de865776e 100644 --- a/src/test/scheduler_tests.cpp +++ b/src/test/scheduler_tests.cpp @@ -8,8 +8,6 @@ #include "test/test_bitcoin.h" #include <boost/bind.hpp> -#include <boost/random/mersenne_twister.hpp> -#include <boost/random/uniform_int_distribution.hpp> #include <boost/thread.hpp> #include <boost/test/unit_test.hpp> @@ -56,10 +54,10 @@ BOOST_AUTO_TEST_CASE(manythreads) boost::mutex counterMutex[10]; int counter[10] = { 0 }; - boost::random::mt19937 rng(42); - boost::random::uniform_int_distribution<> zeroToNine(0, 9); - boost::random::uniform_int_distribution<> randomMsec(-11, 1000); - boost::random::uniform_int_distribution<> randomDelta(-1000, 1000); + FastRandomContext rng(42); + auto zeroToNine = [](FastRandomContext& rc) -> int { return rc.randrange(10); }; // [0, 9] + auto randomMsec = [](FastRandomContext& rc) -> int { return -11 + rc.randrange(1012); }; // [-11, 1000] + auto randomDelta = [](FastRandomContext& rc) -> int { return -1000 + rc.randrange(2001); }; // [-1000, 1000] boost::chrono::system_clock::time_point start = boost::chrono::system_clock::now(); boost::chrono::system_clock::time_point now = start; diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index f8fd8cc30c..0789b2e80c 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -2,6 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "consensus/tx_verify.h" #include "core_io.h" #include "key.h" #include "keystore.h" @@ -111,7 +112,8 @@ BOOST_AUTO_TEST_CASE(sign) { CScript sigSave = txTo[i].vin[0].scriptSig; txTo[i].vin[0].scriptSig = txTo[j].vin[0].scriptSig; - bool sigOK = CScriptCheck(CCoins(txFrom, 0), txTo[i], 0, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC, false, &txdata)(); + const CTxOut& output = txFrom.vout[txTo[i].vin[0].prevout.n]; + bool sigOK = CScriptCheck(output.scriptPubKey, output.nValue, txTo[i], 0, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC, false, &txdata)(); if (i == j) BOOST_CHECK_MESSAGE(sigOK, strprintf("VerifySignature %d %d", i, j)); else @@ -315,7 +317,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard) txFrom.vout[6].scriptPubKey = GetScriptForDestination(CScriptID(twentySigops)); txFrom.vout[6].nValue = 6000; - coins.ModifyCoins(txFrom.GetHash())->FromTx(txFrom, 0); + AddCoins(coins, txFrom, 0); CMutableTransaction txTo; txTo.vout.resize(1); diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 7601034791..1bb191c73d 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -927,7 +927,7 @@ BOOST_AUTO_TEST_CASE(script_build) std::string strGen; - BOOST_FOREACH(TestBuilder& test, tests) { + for (TestBuilder& test : tests) { test.Test(); std::string str = JSONPrettyPrint(test.GetJSON()); #ifndef UPDATE_JSON_TESTS @@ -1033,7 +1033,7 @@ sign_multisig(CScript scriptPubKey, std::vector<CKey> keys, CTransaction transac // and vice-versa) // result << OP_0; - BOOST_FOREACH(const CKey &key, keys) + for (const CKey &key : keys) { std::vector<unsigned char> vchSig; BOOST_CHECK(key.Sign(hash, vchSig)); @@ -1438,4 +1438,18 @@ BOOST_AUTO_TEST_CASE(script_FindAndDelete) BOOST_CHECK(s == expect); } +BOOST_AUTO_TEST_CASE(script_HasValidOps) +{ + // Exercise the HasValidOps functionality + CScript script; + script = ScriptFromHex("76a9141234567890abcdefa1a2a3a4a5a6a7a8a9a0aaab88ac"); // Normal script + BOOST_CHECK(script.HasValidOps()); + script = ScriptFromHex("76a914ff34567890abcdefa1a2a3a4a5a6a7a8a9a0aaab88ac"); + BOOST_CHECK(script.HasValidOps()); + script = ScriptFromHex("ff88ac"); // Script with OP_INVALIDOPCODE explicit + BOOST_CHECK(!script.HasValidOps()); + script = ScriptFromHex("88acc0"); // Script with undefined opcode + BOOST_CHECK(!script.HasValidOps()); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index 5279cb243b..1ca83a7cf8 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -2,16 +2,15 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "consensus/tx_verify.h" #include "consensus/validation.h" #include "data/sighash.json.h" #include "hash.h" -#include "validation.h" // For CheckTransaction #include "script/interpreter.h" #include "script/script.h" #include "serialize.h" #include "streams.h" #include "test/test_bitcoin.h" -#include "test/test_random.h" #include "util.h" #include "utilstrencodings.h" #include "version.h" @@ -30,7 +29,6 @@ uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, un static const uint256 one(uint256S("0000000000000000000000000000000000000000000000000000000000000001")); if (nIn >= txTo.vin.size()) { - printf("ERROR: SignatureHash(): nIn=%d out of range\n", nIn); return one; } CMutableTransaction txTmp(txTo); @@ -61,7 +59,6 @@ uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, un unsigned int nOut = nIn; if (nOut >= txTmp.vout.size()) { - printf("ERROR: SignatureHash(): nOut=%d out of range\n", nOut); return one; } txTmp.vout.resize(nOut+1); @@ -90,30 +87,30 @@ uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, un void static RandomScript(CScript &script) { static const opcodetype oplist[] = {OP_FALSE, OP_1, OP_2, OP_3, OP_CHECKSIG, OP_IF, OP_VERIF, OP_RETURN, OP_CODESEPARATOR}; script = CScript(); - int ops = (insecure_rand() % 10); + int ops = (InsecureRandRange(10)); for (int i=0; i<ops; i++) - script << oplist[insecure_rand() % (sizeof(oplist)/sizeof(oplist[0]))]; + script << oplist[InsecureRandRange(sizeof(oplist)/sizeof(oplist[0]))]; } void static RandomTransaction(CMutableTransaction &tx, bool fSingle) { - tx.nVersion = insecure_rand(); + tx.nVersion = InsecureRand32(); tx.vin.clear(); tx.vout.clear(); - tx.nLockTime = (insecure_rand() % 2) ? insecure_rand() : 0; - int ins = (insecure_rand() % 4) + 1; - int outs = fSingle ? ins : (insecure_rand() % 4) + 1; + tx.nLockTime = (InsecureRandBool()) ? InsecureRand32() : 0; + int ins = (InsecureRandBits(2)) + 1; + int outs = fSingle ? ins : (InsecureRandBits(2)) + 1; for (int in = 0; in < ins; in++) { tx.vin.push_back(CTxIn()); CTxIn &txin = tx.vin.back(); - txin.prevout.hash = GetRandHash(); - txin.prevout.n = insecure_rand() % 4; + txin.prevout.hash = InsecureRand256(); + txin.prevout.n = InsecureRandBits(2); RandomScript(txin.scriptSig); - txin.nSequence = (insecure_rand() % 2) ? insecure_rand() : (unsigned int)-1; + txin.nSequence = (InsecureRandBool()) ? InsecureRand32() : (unsigned int)-1; } for (int out = 0; out < outs; out++) { tx.vout.push_back(CTxOut()); CTxOut &txout = tx.vout.back(); - txout.nValue = insecure_rand() % 100000000; + txout.nValue = InsecureRandRange(100000000); RandomScript(txout.scriptPubKey); } } @@ -122,7 +119,7 @@ BOOST_FIXTURE_TEST_SUITE(sighash_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(sighash_test) { - seed_insecure_rand(false); + SeedInsecureRand(false); #if defined(PRINT_SIGHASH_JSON) std::cout << "[\n"; @@ -134,12 +131,12 @@ BOOST_AUTO_TEST_CASE(sighash_test) nRandomTests = 500; #endif for (int i=0; i<nRandomTests; i++) { - int nHashType = insecure_rand(); + int nHashType = InsecureRand32(); CMutableTransaction txTo; RandomTransaction(txTo, (nHashType & 0x1f) == SIGHASH_SINGLE); CScript scriptCode; RandomScript(scriptCode); - int nIn = insecure_rand() % txTo.vin.size(); + int nIn = InsecureRandRange(txTo.vin.size()); uint256 sh, sho; sho = SignatureHashOld(scriptCode, txTo, nIn, nHashType); diff --git a/src/test/sigopcount_tests.cpp b/src/test/sigopcount_tests.cpp index 13d8911f03..eddb80aed5 100644 --- a/src/test/sigopcount_tests.cpp +++ b/src/test/sigopcount_tests.cpp @@ -2,7 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "validation.h" +#include "consensus/tx_verify.h" #include "pubkey.h" #include "key.h" #include "script/script.h" @@ -12,7 +12,6 @@ #include <vector> -#include <boost/foreach.hpp> #include <boost/test/unit_test.hpp> // Helpers: @@ -102,7 +101,7 @@ void BuildTxs(CMutableTransaction& spendingTx, CCoinsViewCache& coins, CMutableT spendingTx.vout[0].nValue = 1; spendingTx.vout[0].scriptPubKey = CScript(); - coins.ModifyCoins(creationTx.GetHash())->FromTx(creationTx, 0); + AddCoins(coins, creationTx, 0); } BOOST_AUTO_TEST_CASE(GetTxSigOpCost) diff --git a/src/test/skiplist_tests.cpp b/src/test/skiplist_tests.cpp index 0b2fe0ef9d..77c321cdf6 100644 --- a/src/test/skiplist_tests.cpp +++ b/src/test/skiplist_tests.cpp @@ -5,7 +5,6 @@ #include "chain.h" #include "util.h" #include "test/test_bitcoin.h" -#include "test/test_random.h" #include <vector> @@ -35,8 +34,8 @@ BOOST_AUTO_TEST_CASE(skiplist_test) } for (int i=0; i < 1000; i++) { - int from = insecure_rand() % (SKIPLIST_LENGTH - 1); - int to = insecure_rand() % (from + 1); + int from = InsecureRandRange(SKIPLIST_LENGTH - 1); + int to = InsecureRandRange(from + 1); BOOST_CHECK(vIndex[SKIPLIST_LENGTH - 1].GetAncestor(from) == &vIndex[from]); BOOST_CHECK(vIndex[from].GetAncestor(to) == &vIndex[to]); @@ -78,7 +77,7 @@ BOOST_AUTO_TEST_CASE(getlocator_test) // Test 100 random starting points for locators. for (int n=0; n<100; n++) { - int r = insecure_rand() % 150000; + int r = InsecureRandRange(150000); CBlockIndex* tip = (r < 100000) ? &vBlocksMain[r] : &vBlocksSide[r - 100000]; CBlockLocator locator = chain.GetLocator(tip); @@ -116,7 +115,7 @@ BOOST_AUTO_TEST_CASE(findearliestatleast_test) } else { // randomly choose something in the range [MTP, MTP*2] int64_t medianTimePast = vBlocksMain[i].GetMedianTimePast(); - int r = insecure_rand() % medianTimePast; + int r = InsecureRandRange(medianTimePast); vBlocksMain[i].nTime = r + medianTimePast; vBlocksMain[i].nTimeMax = std::max(vBlocksMain[i].nTime, vBlocksMain[i-1].nTimeMax); } @@ -135,7 +134,7 @@ BOOST_AUTO_TEST_CASE(findearliestatleast_test) // Verify that FindEarliestAtLeast is correct. for (unsigned int i=0; i<10000; ++i) { // Pick a random element in vBlocksMain. - int r = insecure_rand() % vBlocksMain.size(); + int r = InsecureRandRange(vBlocksMain.size()); int64_t test_time = vBlocksMain[r].nTime; CBlockIndex *ret = chain.FindEarliestAtLeast(test_time); BOOST_CHECK(ret->nTimeMax >= test_time); @@ -143,4 +142,39 @@ BOOST_AUTO_TEST_CASE(findearliestatleast_test) BOOST_CHECK(vBlocksMain[r].GetAncestor(ret->nHeight) == ret); } } + +BOOST_AUTO_TEST_CASE(findearliestatleast_edge_test) +{ + std::list<CBlockIndex> blocks; + for (unsigned int timeMax : {100, 100, 100, 200, 200, 200, 300, 300, 300}) { + CBlockIndex* prev = blocks.empty() ? nullptr : &blocks.back(); + blocks.emplace_back(); + blocks.back().nHeight = prev ? prev->nHeight + 1 : 0; + blocks.back().pprev = prev; + blocks.back().BuildSkip(); + blocks.back().nTimeMax = timeMax; + } + + CChain chain; + chain.SetTip(&blocks.back()); + + BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(50)->nHeight, 0); + BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(100)->nHeight, 0); + BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(150)->nHeight, 3); + BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(200)->nHeight, 3); + BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(250)->nHeight, 6); + BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(300)->nHeight, 6); + BOOST_CHECK(!chain.FindEarliestAtLeast(350)); + + BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(0)->nHeight, 0); + BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(-1)->nHeight, 0); + + BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(std::numeric_limits<int64_t>::min())->nHeight, 0); + BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(std::numeric_limits<unsigned int>::min())->nHeight, 0); + BOOST_CHECK_EQUAL(chain.FindEarliestAtLeast(-int64_t(std::numeric_limits<unsigned int>::max()) - 1)->nHeight, 0); + BOOST_CHECK(!chain.FindEarliestAtLeast(std::numeric_limits<int64_t>::max())); + BOOST_CHECK(!chain.FindEarliestAtLeast(std::numeric_limits<unsigned int>::max())); + BOOST_CHECK(!chain.FindEarliestAtLeast(int64_t(std::numeric_limits<unsigned int>::max()) + 1)); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/streams_tests.cpp b/src/test/streams_tests.cpp index 94b5cc119b..af2a152aa5 100644 --- a/src/test/streams_tests.cpp +++ b/src/test/streams_tests.cpp @@ -7,7 +7,6 @@ #include "test/test_bitcoin.h" #include <boost/assign/std/vector.hpp> // for 'operator+=()' -#include <boost/assert.hpp> #include <boost/test/unit_test.hpp> using namespace boost::assign; // bring 'operator+=()' into scope diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index cb625bda11..c60379982e 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -25,8 +25,6 @@ #include <memory> -#include <boost/thread.hpp> - uint256 insecure_rand_seed = GetRandHash(); FastRandomContext insecure_rand_ctx(insecure_rand_seed); @@ -35,6 +33,7 @@ extern void noui_connect(); BasicTestingSetup::BasicTestingSetup(const std::string& chainName) { + RandomInit(); ECC_Start(); SetupEnvironment(); SetupNetworking(); @@ -59,7 +58,7 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha RegisterAllCoreRPCCommands(tableRPC); ClearDatadirCache(); - pathTemp = GetTempPath() / strprintf("test_bitcoin_%lu_%i", (unsigned long)GetTime(), (int)(GetRand(100000))); + pathTemp = GetTempPath() / strprintf("test_bitcoin_%lu_%i", (unsigned long)GetTime(), (int)(InsecureRandRange(100000))); fs::create_directories(pathTemp); ForceSetArg("-datadir", pathTemp.string()); mempool.setSanityCheck(1.0); @@ -121,7 +120,7 @@ TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransaction>& // Replace mempool-selected txns with just coinbase plus passed-in txns: block.vtx.resize(1); - BOOST_FOREACH(const CMutableTransaction& tx, txns) + for (const CMutableTransaction& tx : txns) block.vtx.push_back(MakeTransactionRef(tx)); // IncrementExtraNonce creates a valid coinbase and merkleRoot unsigned int extraNonce = 0; diff --git a/src/test/test_bitcoin.h b/src/test/test_bitcoin.h index 60a86d8c48..c9e4a3427f 100644 --- a/src/test/test_bitcoin.h +++ b/src/test/test_bitcoin.h @@ -9,11 +9,31 @@ #include "fs.h" #include "key.h" #include "pubkey.h" +#include "random.h" #include "txdb.h" #include "txmempool.h" #include <boost/thread.hpp> +extern uint256 insecure_rand_seed; +extern FastRandomContext insecure_rand_ctx; + +static inline void SeedInsecureRand(bool fDeterministic = false) +{ + if (fDeterministic) { + insecure_rand_seed = uint256(); + } else { + insecure_rand_seed = GetRandHash(); + } + insecure_rand_ctx = FastRandomContext(insecure_rand_seed); +} + +static inline uint32_t InsecureRand32() { return insecure_rand_ctx.rand32(); } +static inline uint256 InsecureRand256() { return insecure_rand_ctx.rand256(); } +static inline uint64_t InsecureRandBits(int bits) { return insecure_rand_ctx.randbits(bits); } +static inline uint64_t InsecureRandRange(uint64_t range) { return insecure_rand_ctx.randrange(range); } +static inline bool InsecureRandBool() { return insecure_rand_ctx.randbool(); } + /** Basic testing setup. * This just configures logging and chain parameters. */ diff --git a/src/test/test_bitcoin_fuzzy.cpp b/src/test/test_bitcoin_fuzzy.cpp index c4983f6f5c..de14251601 100644 --- a/src/test/test_bitcoin_fuzzy.cpp +++ b/src/test/test_bitcoin_fuzzy.cpp @@ -59,9 +59,8 @@ bool read_stdin(std::vector<char> &data) { return length==0; } -int main(int argc, char **argv) +int do_fuzz() { - ECCVerifyHandle globalVerifyHandle; std::vector<char> buffer; if (!read_stdin(buffer)) return 0; @@ -169,8 +168,8 @@ int main(int argc, char **argv) { try { - CCoins block; - ds >> block; + Coin coin; + ds >> coin; } catch (const std::ios_base::failure& e) {return 0;} break; } @@ -256,3 +255,23 @@ int main(int argc, char **argv) return 0; } +int main(int argc, char **argv) +{ + ECCVerifyHandle globalVerifyHandle; +#ifdef __AFL_INIT + // Enable AFL deferred forkserver mode. Requires compilation using + // afl-clang-fast++. See fuzzing.md for details. + __AFL_INIT(); +#endif + +#ifdef __AFL_LOOP + // Enable AFL persistent mode. Requires compilation using afl-clang-fast++. + // See fuzzing.md for details. + while (__AFL_LOOP(1000)) { + do_fuzz(); + } + return 0; +#else + return do_fuzz(); +#endif +} diff --git a/src/test/test_random.h b/src/test/test_random.h deleted file mode 100644 index 318c44df4d..0000000000 --- a/src/test/test_random.h +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2016 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef BITCOIN_TEST_RANDOM_H -#define BITCOIN_TEST_RANDOM_H - -#include "random.h" - -extern uint256 insecure_rand_seed; -extern FastRandomContext insecure_rand_ctx; - -static inline void seed_insecure_rand(bool fDeterministic = false) -{ - if (fDeterministic) { - insecure_rand_seed = uint256(); - } else { - insecure_rand_seed = GetRandHash(); - } - insecure_rand_ctx = FastRandomContext(insecure_rand_seed); -} - -static inline uint32_t insecure_rand(void) -{ - return insecure_rand_ctx.rand32(); -} - -#endif diff --git a/src/test/torcontrol_tests.cpp b/src/test/torcontrol_tests.cpp new file mode 100644 index 0000000000..b7affaacde --- /dev/null +++ b/src/test/torcontrol_tests.cpp @@ -0,0 +1,199 @@ +// Copyright (c) 2017 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// +#include "test/test_bitcoin.h" +#include "torcontrol.cpp" + +#include <boost/test/unit_test.hpp> + + +BOOST_FIXTURE_TEST_SUITE(torcontrol_tests, BasicTestingSetup) + +void CheckSplitTorReplyLine(std::string input, std::string command, std::string args) +{ + BOOST_TEST_MESSAGE(std::string("CheckSplitTorReplyLine(") + input + ")"); + auto ret = SplitTorReplyLine(input); + BOOST_CHECK_EQUAL(ret.first, command); + BOOST_CHECK_EQUAL(ret.second, args); +} + +BOOST_AUTO_TEST_CASE(util_SplitTorReplyLine) +{ + // Data we should receive during normal usage + CheckSplitTorReplyLine( + "PROTOCOLINFO PIVERSION", + "PROTOCOLINFO", "PIVERSION"); + CheckSplitTorReplyLine( + "AUTH METHODS=COOKIE,SAFECOOKIE COOKIEFILE=\"/home/x/.tor/control_auth_cookie\"", + "AUTH", "METHODS=COOKIE,SAFECOOKIE COOKIEFILE=\"/home/x/.tor/control_auth_cookie\""); + CheckSplitTorReplyLine( + "AUTH METHODS=NULL", + "AUTH", "METHODS=NULL"); + CheckSplitTorReplyLine( + "AUTH METHODS=HASHEDPASSWORD", + "AUTH", "METHODS=HASHEDPASSWORD"); + CheckSplitTorReplyLine( + "VERSION Tor=\"0.2.9.8 (git-a0df013ea241b026)\"", + "VERSION", "Tor=\"0.2.9.8 (git-a0df013ea241b026)\""); + CheckSplitTorReplyLine( + "AUTHCHALLENGE SERVERHASH=aaaa SERVERNONCE=bbbb", + "AUTHCHALLENGE", "SERVERHASH=aaaa SERVERNONCE=bbbb"); + + // Other valid inputs + CheckSplitTorReplyLine("COMMAND", "COMMAND", ""); + CheckSplitTorReplyLine("COMMAND SOME ARGS", "COMMAND", "SOME ARGS"); + + // These inputs are valid because PROTOCOLINFO accepts an OtherLine that is + // just an OptArguments, which enables multiple spaces to be present + // between the command and arguments. + CheckSplitTorReplyLine("COMMAND ARGS", "COMMAND", " ARGS"); + CheckSplitTorReplyLine("COMMAND EVEN+more ARGS", "COMMAND", " EVEN+more ARGS"); +} + +void CheckParseTorReplyMapping(std::string input, std::map<std::string,std::string> expected) +{ + BOOST_TEST_MESSAGE(std::string("CheckParseTorReplyMapping(") + input + ")"); + auto ret = ParseTorReplyMapping(input); + BOOST_CHECK_EQUAL(ret.size(), expected.size()); + auto r_it = ret.begin(); + auto e_it = expected.begin(); + while (r_it != ret.end() && e_it != expected.end()) { + BOOST_CHECK_EQUAL(r_it->first, e_it->first); + BOOST_CHECK_EQUAL(r_it->second, e_it->second); + r_it++; + e_it++; + } +} + +BOOST_AUTO_TEST_CASE(util_ParseTorReplyMapping) +{ + // Data we should receive during normal usage + CheckParseTorReplyMapping( + "METHODS=COOKIE,SAFECOOKIE COOKIEFILE=\"/home/x/.tor/control_auth_cookie\"", { + {"METHODS", "COOKIE,SAFECOOKIE"}, + {"COOKIEFILE", "/home/x/.tor/control_auth_cookie"}, + }); + CheckParseTorReplyMapping( + "METHODS=NULL", { + {"METHODS", "NULL"}, + }); + CheckParseTorReplyMapping( + "METHODS=HASHEDPASSWORD", { + {"METHODS", "HASHEDPASSWORD"}, + }); + CheckParseTorReplyMapping( + "Tor=\"0.2.9.8 (git-a0df013ea241b026)\"", { + {"Tor", "0.2.9.8 (git-a0df013ea241b026)"}, + }); + CheckParseTorReplyMapping( + "SERVERHASH=aaaa SERVERNONCE=bbbb", { + {"SERVERHASH", "aaaa"}, + {"SERVERNONCE", "bbbb"}, + }); + CheckParseTorReplyMapping( + "ServiceID=exampleonion1234", { + {"ServiceID", "exampleonion1234"}, + }); + CheckParseTorReplyMapping( + "PrivateKey=RSA1024:BLOB", { + {"PrivateKey", "RSA1024:BLOB"}, + }); + CheckParseTorReplyMapping( + "ClientAuth=bob:BLOB", { + {"ClientAuth", "bob:BLOB"}, + }); + + // Other valid inputs + CheckParseTorReplyMapping( + "Foo=Bar=Baz Spam=Eggs", { + {"Foo", "Bar=Baz"}, + {"Spam", "Eggs"}, + }); + CheckParseTorReplyMapping( + "Foo=\"Bar=Baz\"", { + {"Foo", "Bar=Baz"}, + }); + CheckParseTorReplyMapping( + "Foo=\"Bar Baz\"", { + {"Foo", "Bar Baz"}, + }); + + // Escapes + CheckParseTorReplyMapping( + "Foo=\"Bar\\ Baz\"", { + {"Foo", "Bar Baz"}, + }); + CheckParseTorReplyMapping( + "Foo=\"Bar\\Baz\"", { + {"Foo", "BarBaz"}, + }); + CheckParseTorReplyMapping( + "Foo=\"Bar\\@Baz\"", { + {"Foo", "Bar@Baz"}, + }); + CheckParseTorReplyMapping( + "Foo=\"Bar\\\"Baz\" Spam=\"\\\"Eggs\\\"\"", { + {"Foo", "Bar\"Baz"}, + {"Spam", "\"Eggs\""}, + }); + CheckParseTorReplyMapping( + "Foo=\"Bar\\\\Baz\"", { + {"Foo", "Bar\\Baz"}, + }); + + // C escapes + CheckParseTorReplyMapping( + "Foo=\"Bar\\nBaz\\t\" Spam=\"\\rEggs\" Octals=\"\\1a\\11\\17\\18\\81\\377\\378\\400\\2222\" Final=Check", { + {"Foo", "Bar\nBaz\t"}, + {"Spam", "\rEggs"}, + {"Octals", "\1a\11\17\1" "881\377\37" "8\40" "0\222" "2"}, + {"Final", "Check"}, + }); + CheckParseTorReplyMapping( + "Valid=Mapping Escaped=\"Escape\\\\\"", { + {"Valid", "Mapping"}, + {"Escaped", "Escape\\"}, + }); + CheckParseTorReplyMapping( + "Valid=Mapping Bare=\"Escape\\\"", {}); + CheckParseTorReplyMapping( + "OneOctal=\"OneEnd\\1\" TwoOctal=\"TwoEnd\\11\"", { + {"OneOctal", "OneEnd\1"}, + {"TwoOctal", "TwoEnd\11"}, + }); + + // Special handling for null case + // (needed because string comparison reads the null as end-of-string) + BOOST_TEST_MESSAGE(std::string("CheckParseTorReplyMapping(Null=\"\\0\")")); + auto ret = ParseTorReplyMapping("Null=\"\\0\""); + BOOST_CHECK_EQUAL(ret.size(), 1); + auto r_it = ret.begin(); + BOOST_CHECK_EQUAL(r_it->first, "Null"); + BOOST_CHECK_EQUAL(r_it->second.size(), 1); + BOOST_CHECK_EQUAL(r_it->second[0], '\0'); + + // A more complex valid grammar. PROTOCOLINFO accepts a VersionLine that + // takes a key=value pair followed by an OptArguments, making this valid. + // Because an OptArguments contains no semantic data, there is no point in + // parsing it. + CheckParseTorReplyMapping( + "SOME=args,here MORE optional=arguments here", { + {"SOME", "args,here"}, + }); + + // Inputs that are effectively invalid under the target grammar. + // PROTOCOLINFO accepts an OtherLine that is just an OptArguments, which + // would make these inputs valid. However, + // - This parser is never used in that situation, because the + // SplitTorReplyLine parser enables OtherLine to be skipped. + // - Even if these were valid, an OptArguments contains no semantic data, + // so there is no point in parsing it. + CheckParseTorReplyMapping("ARGS", {}); + CheckParseTorReplyMapping("MORE ARGS", {}); + CheckParseTorReplyMapping("MORE ARGS", {}); + CheckParseTorReplyMapping("EVEN more=ARGS", {}); + CheckParseTorReplyMapping("EVEN+more ARGS", {}); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 3b5da4980b..778d2fd742 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -8,11 +8,12 @@ #include "clientversion.h" #include "checkqueue.h" +#include "consensus/tx_verify.h" #include "consensus/validation.h" #include "core_io.h" #include "key.h" #include "keystore.h" -#include "validation.h" // For CheckTransaction +#include "validation.h" #include "policy/policy.h" #include "script/script.h" #include "script/sign.h" @@ -25,9 +26,7 @@ #include <boost/algorithm/string/classification.hpp> #include <boost/algorithm/string/split.hpp> -#include <boost/assign/list_of.hpp> #include <boost/test/unit_test.hpp> -#include <boost/assign/list_of.hpp> #include <boost/foreach.hpp> #include <univalue.h> @@ -37,24 +36,25 @@ typedef std::vector<unsigned char> valtype; // In script_tests.cpp extern UniValue read_json(const std::string& jsondata); -static std::map<std::string, unsigned int> mapFlagNames = boost::assign::map_list_of - (std::string("NONE"), (unsigned int)SCRIPT_VERIFY_NONE) - (std::string("P2SH"), (unsigned int)SCRIPT_VERIFY_P2SH) - (std::string("STRICTENC"), (unsigned int)SCRIPT_VERIFY_STRICTENC) - (std::string("DERSIG"), (unsigned int)SCRIPT_VERIFY_DERSIG) - (std::string("LOW_S"), (unsigned int)SCRIPT_VERIFY_LOW_S) - (std::string("SIGPUSHONLY"), (unsigned int)SCRIPT_VERIFY_SIGPUSHONLY) - (std::string("MINIMALDATA"), (unsigned int)SCRIPT_VERIFY_MINIMALDATA) - (std::string("NULLDUMMY"), (unsigned int)SCRIPT_VERIFY_NULLDUMMY) - (std::string("DISCOURAGE_UPGRADABLE_NOPS"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) - (std::string("CLEANSTACK"), (unsigned int)SCRIPT_VERIFY_CLEANSTACK) - (std::string("MINIMALIF"), (unsigned int)SCRIPT_VERIFY_MINIMALIF) - (std::string("NULLFAIL"), (unsigned int)SCRIPT_VERIFY_NULLFAIL) - (std::string("CHECKLOCKTIMEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY) - (std::string("CHECKSEQUENCEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKSEQUENCEVERIFY) - (std::string("WITNESS"), (unsigned int)SCRIPT_VERIFY_WITNESS) - (std::string("DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM) - (std::string("WITNESS_PUBKEYTYPE"), (unsigned int)SCRIPT_VERIFY_WITNESS_PUBKEYTYPE); +static std::map<std::string, unsigned int> mapFlagNames = { + {std::string("NONE"), (unsigned int)SCRIPT_VERIFY_NONE}, + {std::string("P2SH"), (unsigned int)SCRIPT_VERIFY_P2SH}, + {std::string("STRICTENC"), (unsigned int)SCRIPT_VERIFY_STRICTENC}, + {std::string("DERSIG"), (unsigned int)SCRIPT_VERIFY_DERSIG}, + {std::string("LOW_S"), (unsigned int)SCRIPT_VERIFY_LOW_S}, + {std::string("SIGPUSHONLY"), (unsigned int)SCRIPT_VERIFY_SIGPUSHONLY}, + {std::string("MINIMALDATA"), (unsigned int)SCRIPT_VERIFY_MINIMALDATA}, + {std::string("NULLDUMMY"), (unsigned int)SCRIPT_VERIFY_NULLDUMMY}, + {std::string("DISCOURAGE_UPGRADABLE_NOPS"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS}, + {std::string("CLEANSTACK"), (unsigned int)SCRIPT_VERIFY_CLEANSTACK}, + {std::string("MINIMALIF"), (unsigned int)SCRIPT_VERIFY_MINIMALIF}, + {std::string("NULLFAIL"), (unsigned int)SCRIPT_VERIFY_NULLFAIL}, + {std::string("CHECKLOCKTIMEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY}, + {std::string("CHECKSEQUENCEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKSEQUENCEVERIFY}, + {std::string("WITNESS"), (unsigned int)SCRIPT_VERIFY_WITNESS}, + {std::string("DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM}, + {std::string("WITNESS_PUBKEYTYPE"), (unsigned int)SCRIPT_VERIFY_WITNESS_PUBKEYTYPE}, +}; unsigned int ParseScriptFlags(std::string strFlags) { @@ -65,7 +65,7 @@ unsigned int ParseScriptFlags(std::string strFlags) std::vector<std::string> words; boost::algorithm::split(words, strFlags, boost::algorithm::is_any_of(",")); - BOOST_FOREACH(std::string word, words) + for (std::string word : words) { if (!mapFlagNames.count(word)) BOOST_ERROR("Bad test: unknown verification flag '" << word << "'"); @@ -306,14 +306,14 @@ SetupDummyInputs(CBasicKeyStore& keystoreRet, CCoinsViewCache& coinsRet) dummyTransactions[0].vout[0].scriptPubKey << ToByteVector(key[0].GetPubKey()) << OP_CHECKSIG; dummyTransactions[0].vout[1].nValue = 50*CENT; dummyTransactions[0].vout[1].scriptPubKey << ToByteVector(key[1].GetPubKey()) << OP_CHECKSIG; - coinsRet.ModifyCoins(dummyTransactions[0].GetHash())->FromTx(dummyTransactions[0], 0); + AddCoins(coinsRet, dummyTransactions[0], 0); dummyTransactions[1].vout.resize(2); dummyTransactions[1].vout[0].nValue = 21*CENT; dummyTransactions[1].vout[0].scriptPubKey = GetScriptForDestination(key[2].GetPubKey().GetID()); dummyTransactions[1].vout[1].nValue = 22*CENT; dummyTransactions[1].vout[1].scriptPubKey = GetScriptForDestination(key[3].GetPubKey().GetID()); - coinsRet.ModifyCoins(dummyTransactions[1].GetHash())->FromTx(dummyTransactions[1], 0); + AddCoins(coinsRet, dummyTransactions[1], 0); return dummyTransactions; } @@ -393,7 +393,7 @@ void CheckWithFlag(const CTransactionRef& output, const CMutableTransaction& inp static CScript PushAll(const std::vector<valtype>& values) { CScript result; - BOOST_FOREACH(const valtype& v, values) { + for (const valtype& v : values) { if (v.size() == 0) { result << OP_0; } else if (v.size() == 1 && v[0] >= 1 && v[0] <= 16) { @@ -469,19 +469,20 @@ BOOST_AUTO_TEST_CASE(test_big_witness_transaction) { for (int i=0; i<20; i++) threadGroup.create_thread(boost::bind(&CCheckQueue<CScriptCheck>::Thread, boost::ref(scriptcheckqueue))); - CCoins coins; - coins.nVersion = 1; - coins.fCoinBase = false; + std::vector<Coin> coins; for(uint32_t i = 0; i < mtx.vin.size(); i++) { - CTxOut txout; - txout.nValue = 1000; - txout.scriptPubKey = scriptPubKey; - coins.vout.push_back(txout); + Coin coin; + coin.nHeight = 1; + coin.fCoinBase = false; + coin.out.nValue = 1000; + coin.out.scriptPubKey = scriptPubKey; + coins.emplace_back(std::move(coin)); } for(uint32_t i = 0; i < mtx.vin.size(); i++) { std::vector<CScriptCheck> vChecks; - CScriptCheck check(coins, tx, i, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false, &txdata); + const CTxOut& output = coins[tx.vin[i].prevout.n].out; + CScriptCheck check(output.scriptPubKey, output.nValue, tx, i, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false, &txdata); vChecks.push_back(CScriptCheck()); check.swap(vChecks.back()); control.Add(vChecks); diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 5da4907f06..5e9dfb730b 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -10,15 +10,12 @@ #include "utilstrencodings.h" #include "utilmoneystr.h" #include "test/test_bitcoin.h" -#include "test/test_random.h" #include <stdint.h> #include <vector> #include <boost/test/unit_test.hpp> -extern std::map<std::string, std::string> mapArgs; - BOOST_FIXTURE_TEST_SUITE(util_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(util_criticalsection) @@ -100,52 +97,67 @@ BOOST_AUTO_TEST_CASE(util_DateTimeStrFormat) BOOST_CHECK_EQUAL(DateTimeStrFormat("%a, %d %b %Y %H:%M:%S +0000", 1317425777), "Fri, 30 Sep 2011 23:36:17 +0000"); } +class TestArgsManager : public ArgsManager +{ +public: + std::map<std::string, std::string>& GetMapArgs() + { + return mapArgs; + }; + const std::map<std::string, std::vector<std::string> >& GetMapMultiArgs() + { + return mapMultiArgs; + }; +}; + BOOST_AUTO_TEST_CASE(util_ParseParameters) { + TestArgsManager testArgs; const char *argv_test[] = {"-ignored", "-a", "-b", "-ccc=argument", "-ccc=multiple", "f", "-d=e"}; - ParseParameters(0, (char**)argv_test); - BOOST_CHECK(mapArgs.empty() && mapMultiArgs.empty()); + testArgs.ParseParameters(0, (char**)argv_test); + BOOST_CHECK(testArgs.GetMapArgs().empty() && testArgs.GetMapMultiArgs().empty()); - ParseParameters(1, (char**)argv_test); - BOOST_CHECK(mapArgs.empty() && mapMultiArgs.empty()); + testArgs.ParseParameters(1, (char**)argv_test); + BOOST_CHECK(testArgs.GetMapArgs().empty() && testArgs.GetMapMultiArgs().empty()); - ParseParameters(5, (char**)argv_test); + testArgs.ParseParameters(5, (char**)argv_test); // expectation: -ignored is ignored (program name argument), // -a, -b and -ccc end up in map, -d ignored because it is after // a non-option argument (non-GNU option parsing) - BOOST_CHECK(mapArgs.size() == 3 && mapMultiArgs.size() == 3); - BOOST_CHECK(IsArgSet("-a") && IsArgSet("-b") && IsArgSet("-ccc") - && !IsArgSet("f") && !IsArgSet("-d")); - BOOST_CHECK(mapMultiArgs.count("-a") && mapMultiArgs.count("-b") && mapMultiArgs.count("-ccc") - && !mapMultiArgs.count("f") && !mapMultiArgs.count("-d")); - - BOOST_CHECK(mapArgs["-a"] == "" && mapArgs["-ccc"] == "multiple"); - BOOST_CHECK(mapMultiArgs.at("-ccc").size() == 2); + BOOST_CHECK(testArgs.GetMapArgs().size() == 3 && testArgs.GetMapMultiArgs().size() == 3); + BOOST_CHECK(testArgs.IsArgSet("-a") && testArgs.IsArgSet("-b") && testArgs.IsArgSet("-ccc") + && !testArgs.IsArgSet("f") && !testArgs.IsArgSet("-d")); + BOOST_CHECK(testArgs.GetMapMultiArgs().count("-a") && testArgs.GetMapMultiArgs().count("-b") && testArgs.GetMapMultiArgs().count("-ccc") + && !testArgs.GetMapMultiArgs().count("f") && !testArgs.GetMapMultiArgs().count("-d")); + + BOOST_CHECK(testArgs.GetMapArgs()["-a"] == "" && testArgs.GetMapArgs()["-ccc"] == "multiple"); + BOOST_CHECK(testArgs.GetArgs("-ccc").size() == 2); } BOOST_AUTO_TEST_CASE(util_GetArg) { - mapArgs.clear(); - mapArgs["strtest1"] = "string..."; + TestArgsManager testArgs; + testArgs.GetMapArgs().clear(); + testArgs.GetMapArgs()["strtest1"] = "string..."; // strtest2 undefined on purpose - mapArgs["inttest1"] = "12345"; - mapArgs["inttest2"] = "81985529216486895"; + testArgs.GetMapArgs()["inttest1"] = "12345"; + testArgs.GetMapArgs()["inttest2"] = "81985529216486895"; // inttest3 undefined on purpose - mapArgs["booltest1"] = ""; + testArgs.GetMapArgs()["booltest1"] = ""; // booltest2 undefined on purpose - mapArgs["booltest3"] = "0"; - mapArgs["booltest4"] = "1"; - - BOOST_CHECK_EQUAL(GetArg("strtest1", "default"), "string..."); - BOOST_CHECK_EQUAL(GetArg("strtest2", "default"), "default"); - BOOST_CHECK_EQUAL(GetArg("inttest1", -1), 12345); - BOOST_CHECK_EQUAL(GetArg("inttest2", -1), 81985529216486895LL); - BOOST_CHECK_EQUAL(GetArg("inttest3", -1), -1); - BOOST_CHECK_EQUAL(GetBoolArg("booltest1", false), true); - BOOST_CHECK_EQUAL(GetBoolArg("booltest2", false), false); - BOOST_CHECK_EQUAL(GetBoolArg("booltest3", false), false); - BOOST_CHECK_EQUAL(GetBoolArg("booltest4", false), true); + testArgs.GetMapArgs()["booltest3"] = "0"; + testArgs.GetMapArgs()["booltest4"] = "1"; + + BOOST_CHECK_EQUAL(testArgs.GetArg("strtest1", "default"), "string..."); + BOOST_CHECK_EQUAL(testArgs.GetArg("strtest2", "default"), "default"); + BOOST_CHECK_EQUAL(testArgs.GetArg("inttest1", -1), 12345); + BOOST_CHECK_EQUAL(testArgs.GetArg("inttest2", -1), 81985529216486895LL); + BOOST_CHECK_EQUAL(testArgs.GetArg("inttest3", -1), -1); + BOOST_CHECK_EQUAL(testArgs.GetBoolArg("booltest1", false), true); + BOOST_CHECK_EQUAL(testArgs.GetBoolArg("booltest2", false), false); + BOOST_CHECK_EQUAL(testArgs.GetBoolArg("booltest3", false), false); + BOOST_CHECK_EQUAL(testArgs.GetBoolArg("booltest4", false), true); } BOOST_AUTO_TEST_CASE(util_FormatMoney) @@ -243,7 +255,7 @@ BOOST_AUTO_TEST_CASE(util_IsHex) BOOST_AUTO_TEST_CASE(util_seed_insecure_rand) { - seed_insecure_rand(true); + SeedInsecureRand(true); for (int mod=2;mod<11;mod++) { int mask = 1; @@ -257,7 +269,7 @@ BOOST_AUTO_TEST_CASE(util_seed_insecure_rand) for (int i = 0; i < 10000; i++) { uint32_t rval; do{ - rval=insecure_rand()&mask; + rval=InsecureRand32()&mask; }while(rval>=(uint32_t)mod); count += rval==0; } diff --git a/src/test/versionbits_tests.cpp b/src/test/versionbits_tests.cpp index e2b5573abd..faa2383d14 100644 --- a/src/test/versionbits_tests.cpp +++ b/src/test/versionbits_tests.cpp @@ -5,7 +5,6 @@ #include "chain.h" #include "versionbits.h" #include "test/test_bitcoin.h" -#include "test/test_random.h" #include "chainparams.h" #include "validation.h" #include "consensus/params.h" @@ -81,7 +80,7 @@ public: VersionBitsTester& TestStateSinceHeight(int height) { for (int i = 0; i < CHECKERS; i++) { - if ((insecure_rand() & ((1 << i) - 1)) == 0) { + if (InsecureRandBits(i) == 0) { BOOST_CHECK_MESSAGE(checker[i].GetStateSinceHeightFor(vpblock.empty() ? NULL : vpblock.back()) == height, strprintf("Test %i for StateSinceHeight", num)); } } @@ -91,7 +90,7 @@ public: VersionBitsTester& TestDefined() { for (int i = 0; i < CHECKERS; i++) { - if ((insecure_rand() & ((1 << i) - 1)) == 0) { + if (InsecureRandBits(i) == 0) { BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? NULL : vpblock.back()) == THRESHOLD_DEFINED, strprintf("Test %i for DEFINED", num)); } } @@ -101,7 +100,7 @@ public: VersionBitsTester& TestStarted() { for (int i = 0; i < CHECKERS; i++) { - if ((insecure_rand() & ((1 << i) - 1)) == 0) { + if (InsecureRandBits(i) == 0) { BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? NULL : vpblock.back()) == THRESHOLD_STARTED, strprintf("Test %i for STARTED", num)); } } @@ -111,7 +110,7 @@ public: VersionBitsTester& TestLockedIn() { for (int i = 0; i < CHECKERS; i++) { - if ((insecure_rand() & ((1 << i) - 1)) == 0) { + if (InsecureRandBits(i) == 0) { BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? NULL : vpblock.back()) == THRESHOLD_LOCKED_IN, strprintf("Test %i for LOCKED_IN", num)); } } @@ -121,7 +120,7 @@ public: VersionBitsTester& TestActive() { for (int i = 0; i < CHECKERS; i++) { - if ((insecure_rand() & ((1 << i) - 1)) == 0) { + if (InsecureRandBits(i) == 0) { BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? NULL : vpblock.back()) == THRESHOLD_ACTIVE, strprintf("Test %i for ACTIVE", num)); } } @@ -131,7 +130,7 @@ public: VersionBitsTester& TestFailed() { for (int i = 0; i < CHECKERS; i++) { - if ((insecure_rand() & ((1 << i) - 1)) == 0) { + if (InsecureRandBits(i) == 0) { BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? NULL : vpblock.back()) == THRESHOLD_FAILED, strprintf("Test %i for FAILED", num)); } } @@ -209,7 +208,8 @@ BOOST_AUTO_TEST_CASE(versionbits_test) } // Sanity checks of version bit deployments - const Consensus::Params &mainnetParams = Params(CBaseChainParams::MAIN).GetConsensus(); + const auto chainParams = CreateChainParams(CBaseChainParams::MAIN); + const Consensus::Params &mainnetParams = chainParams->GetConsensus(); for (int i=0; i<(int) Consensus::MAX_VERSION_BITS_DEPLOYMENTS; i++) { uint32_t bitmask = VersionBitsMask(mainnetParams, (Consensus::DeploymentPos)i); // Make sure that no deployment tries to set an invalid bit. @@ -235,7 +235,8 @@ BOOST_AUTO_TEST_CASE(versionbits_computeblockversion) { // Check that ComputeBlockVersion will set the appropriate bit correctly // on mainnet. - const Consensus::Params &mainnetParams = Params(CBaseChainParams::MAIN).GetConsensus(); + const auto chainParams = CreateChainParams(CBaseChainParams::MAIN); + const Consensus::Params &mainnetParams = chainParams->GetConsensus(); // Use the TESTDUMMY deployment for testing purposes. int64_t bit = mainnetParams.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit; |