Merge branch 'master' into single_prodname
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2011-2013 The Bitcoin Core developers
|
||||
// Copyright (c) 2011-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2011-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2011-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -49,7 +49,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning)
|
||||
CNode dummyNode1(INVALID_SOCKET, addr1, "", true);
|
||||
dummyNode1.nVersion = 1;
|
||||
Misbehaving(dummyNode1.GetId(), 100); // Should get banned
|
||||
SendMessages(&dummyNode1, false);
|
||||
SendMessages(&dummyNode1);
|
||||
BOOST_CHECK(CNode::IsBanned(addr1));
|
||||
BOOST_CHECK(!CNode::IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different IP, not banned
|
||||
|
||||
@@ -57,11 +57,11 @@ BOOST_AUTO_TEST_CASE(DoS_banning)
|
||||
CNode dummyNode2(INVALID_SOCKET, addr2, "", true);
|
||||
dummyNode2.nVersion = 1;
|
||||
Misbehaving(dummyNode2.GetId(), 50);
|
||||
SendMessages(&dummyNode2, false);
|
||||
SendMessages(&dummyNode2);
|
||||
BOOST_CHECK(!CNode::IsBanned(addr2)); // 2 not banned yet...
|
||||
BOOST_CHECK(CNode::IsBanned(addr1)); // ... but 1 still should be
|
||||
Misbehaving(dummyNode2.GetId(), 50);
|
||||
SendMessages(&dummyNode2, false);
|
||||
SendMessages(&dummyNode2);
|
||||
BOOST_CHECK(CNode::IsBanned(addr2));
|
||||
}
|
||||
|
||||
@@ -73,13 +73,13 @@ BOOST_AUTO_TEST_CASE(DoS_banscore)
|
||||
CNode dummyNode1(INVALID_SOCKET, addr1, "", true);
|
||||
dummyNode1.nVersion = 1;
|
||||
Misbehaving(dummyNode1.GetId(), 100);
|
||||
SendMessages(&dummyNode1, false);
|
||||
SendMessages(&dummyNode1);
|
||||
BOOST_CHECK(!CNode::IsBanned(addr1));
|
||||
Misbehaving(dummyNode1.GetId(), 10);
|
||||
SendMessages(&dummyNode1, false);
|
||||
SendMessages(&dummyNode1);
|
||||
BOOST_CHECK(!CNode::IsBanned(addr1));
|
||||
Misbehaving(dummyNode1.GetId(), 1);
|
||||
SendMessages(&dummyNode1, false);
|
||||
SendMessages(&dummyNode1);
|
||||
BOOST_CHECK(CNode::IsBanned(addr1));
|
||||
mapArgs.erase("-banscore");
|
||||
}
|
||||
@@ -95,7 +95,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime)
|
||||
dummyNode.nVersion = 1;
|
||||
|
||||
Misbehaving(dummyNode.GetId(), 100);
|
||||
SendMessages(&dummyNode, false);
|
||||
SendMessages(&dummyNode);
|
||||
BOOST_CHECK(CNode::IsBanned(addr));
|
||||
|
||||
SetMockTime(nStartTime+60*60);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2012-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2013 The Bitcoin Core developers
|
||||
// Copyright (c) 2012-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#include "addrman.h"
|
||||
@@ -6,11 +6,49 @@
|
||||
#include <string>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include "hash.h"
|
||||
#include "random.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class CAddrManTest : public CAddrMan{};
|
||||
class CAddrManTest : public CAddrMan
|
||||
{
|
||||
uint64_t state;
|
||||
|
||||
public:
|
||||
CAddrManTest()
|
||||
{
|
||||
state = 1;
|
||||
}
|
||||
|
||||
//! Ensure that bucket placement is always the same for testing purposes.
|
||||
void MakeDeterministic()
|
||||
{
|
||||
nKey.SetNull();
|
||||
seed_insecure_rand(true);
|
||||
}
|
||||
|
||||
int RandomInt(int nMax)
|
||||
{
|
||||
state = (CHashWriter(SER_GETHASH, 0) << state).GetHash().GetCheapHash();
|
||||
return (unsigned int)(state % nMax);
|
||||
}
|
||||
|
||||
CAddrInfo* Find(const CNetAddr& addr, int* pnId = NULL)
|
||||
{
|
||||
return CAddrMan::Find(addr, pnId);
|
||||
}
|
||||
|
||||
CAddrInfo* Create(const CAddress& addr, const CNetAddr& addrSource, int* pnId = NULL)
|
||||
{
|
||||
return CAddrMan::Create(addr, addrSource, pnId);
|
||||
}
|
||||
|
||||
void Delete(int nId)
|
||||
{
|
||||
CAddrMan::Delete(nId);
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(addrman_tests, BasicTestingSetup)
|
||||
|
||||
@@ -21,7 +59,7 @@ BOOST_AUTO_TEST_CASE(addrman_simple)
|
||||
// Set addrman addr placement to be deterministic.
|
||||
addrman.MakeDeterministic();
|
||||
|
||||
CNetAddr source = CNetAddr("252.2.2.2:8333");
|
||||
CNetAddr source = CNetAddr("252.2.2.2");
|
||||
|
||||
// Test 1: Does Addrman respond correctly when empty.
|
||||
BOOST_CHECK(addrman.size() == 0);
|
||||
@@ -29,26 +67,26 @@ BOOST_AUTO_TEST_CASE(addrman_simple)
|
||||
BOOST_CHECK(addr_null.ToString() == "[::]:0");
|
||||
|
||||
// Test 2: Does Addrman::Add work as expected.
|
||||
CService addr1 = CService("250.1.1.1:8333");
|
||||
CService addr1 = CService("250.1.1.1", 8333);
|
||||
addrman.Add(CAddress(addr1), source);
|
||||
BOOST_CHECK(addrman.size() == 1);
|
||||
CAddrInfo addr_ret1 = addrman.Select();
|
||||
BOOST_CHECK(addr_ret1.ToString() == "250.1.1.1:8333");
|
||||
|
||||
// Test 3: Does IP address deduplication work correctly.
|
||||
// Test 3: Does IP address deduplication work correctly.
|
||||
// Expected dup IP should not be added.
|
||||
CService addr1_dup = CService("250.1.1.1:8333");
|
||||
CService addr1_dup = CService("250.1.1.1", 8333);
|
||||
addrman.Add(CAddress(addr1_dup), source);
|
||||
BOOST_CHECK(addrman.size() == 1);
|
||||
|
||||
|
||||
// Test 5: New table has one addr and we add a diff addr we should
|
||||
// have two addrs.
|
||||
CService addr2 = CService("250.1.1.2:8333");
|
||||
CService addr2 = CService("250.1.1.2", 8333);
|
||||
addrman.Add(CAddress(addr2), source);
|
||||
BOOST_CHECK(addrman.size() == 2);
|
||||
|
||||
// Test 6: AddrMan::Clear() should empty the new table.
|
||||
// Test 6: AddrMan::Clear() should empty the new table.
|
||||
addrman.Clear();
|
||||
BOOST_CHECK(addrman.size() == 0);
|
||||
CAddrInfo addr_null2 = addrman.Select();
|
||||
@@ -62,16 +100,16 @@ BOOST_AUTO_TEST_CASE(addrman_ports)
|
||||
// Set addrman addr placement to be deterministic.
|
||||
addrman.MakeDeterministic();
|
||||
|
||||
CNetAddr source = CNetAddr("252.2.2.2:8333");
|
||||
CNetAddr source = CNetAddr("252.2.2.2");
|
||||
|
||||
BOOST_CHECK(addrman.size() == 0);
|
||||
|
||||
// Test 7; Addr with same IP but diff port does not replace existing addr.
|
||||
CService addr1 = CService("250.1.1.1:8333");
|
||||
CService addr1 = CService("250.1.1.1", 8333);
|
||||
addrman.Add(CAddress(addr1), source);
|
||||
BOOST_CHECK(addrman.size() == 1);
|
||||
|
||||
CService addr1_port = CService("250.1.1.1:8334");
|
||||
CService addr1_port = CService("250.1.1.1", 8334);
|
||||
addrman.Add(CAddress(addr1_port), source);
|
||||
BOOST_CHECK(addrman.size() == 1);
|
||||
CAddrInfo addr_ret2 = addrman.Select();
|
||||
@@ -94,10 +132,10 @@ BOOST_AUTO_TEST_CASE(addrman_select)
|
||||
// Set addrman addr placement to be deterministic.
|
||||
addrman.MakeDeterministic();
|
||||
|
||||
CNetAddr source = CNetAddr("252.2.2.2:8333");
|
||||
CNetAddr source = CNetAddr("252.2.2.2");
|
||||
|
||||
// Test 9: Select from new with 1 addr in new.
|
||||
CService addr1 = CService("250.1.1.1:8333");
|
||||
CService addr1 = CService("250.1.1.1", 8333);
|
||||
addrman.Add(CAddress(addr1), source);
|
||||
BOOST_CHECK(addrman.size() == 1);
|
||||
|
||||
@@ -105,7 +143,6 @@ BOOST_AUTO_TEST_CASE(addrman_select)
|
||||
CAddrInfo addr_ret1 = addrman.Select(newOnly);
|
||||
BOOST_CHECK(addr_ret1.ToString() == "250.1.1.1:8333");
|
||||
|
||||
|
||||
// Test 10: move addr to tried, select from new expected nothing returned.
|
||||
addrman.Good(CAddress(addr1));
|
||||
BOOST_CHECK(addrman.size() == 1);
|
||||
@@ -114,6 +151,39 @@ BOOST_AUTO_TEST_CASE(addrman_select)
|
||||
|
||||
CAddrInfo addr_ret3 = addrman.Select();
|
||||
BOOST_CHECK(addr_ret3.ToString() == "250.1.1.1:8333");
|
||||
|
||||
BOOST_CHECK(addrman.size() == 1);
|
||||
|
||||
|
||||
// Add three addresses to new table.
|
||||
CService addr2 = CService("250.3.1.1", 8333);
|
||||
CService addr3 = CService("250.3.2.2", 9999);
|
||||
CService addr4 = CService("250.3.3.3", 9999);
|
||||
|
||||
addrman.Add(CAddress(addr2), CService("250.3.1.1", 8333));
|
||||
addrman.Add(CAddress(addr3), CService("250.3.1.1", 8333));
|
||||
addrman.Add(CAddress(addr4), CService("250.4.1.1", 8333));
|
||||
|
||||
// Add three addresses to tried table.
|
||||
CService addr5 = CService("250.4.4.4", 8333);
|
||||
CService addr6 = CService("250.4.5.5", 7777);
|
||||
CService addr7 = CService("250.4.6.6", 8333);
|
||||
|
||||
addrman.Add(CAddress(addr5), CService("250.3.1.1", 8333));
|
||||
addrman.Good(CAddress(addr5));
|
||||
addrman.Add(CAddress(addr6), CService("250.3.1.1", 8333));
|
||||
addrman.Good(CAddress(addr6));
|
||||
addrman.Add(CAddress(addr7), CService("250.1.1.3", 8333));
|
||||
addrman.Good(CAddress(addr7));
|
||||
|
||||
// Test 11: 6 addrs + 1 addr from last test = 7.
|
||||
BOOST_CHECK(addrman.size() == 7);
|
||||
|
||||
// Test 12: Select pulls from new and tried regardless of port number.
|
||||
BOOST_CHECK(addrman.Select().ToString() == "250.4.6.6:8333");
|
||||
BOOST_CHECK(addrman.Select().ToString() == "250.3.2.2:9999");
|
||||
BOOST_CHECK(addrman.Select().ToString() == "250.3.3.3:9999");
|
||||
BOOST_CHECK(addrman.Select().ToString() == "250.4.4.4:8333");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(addrman_new_collisions)
|
||||
@@ -123,26 +193,26 @@ BOOST_AUTO_TEST_CASE(addrman_new_collisions)
|
||||
// Set addrman addr placement to be deterministic.
|
||||
addrman.MakeDeterministic();
|
||||
|
||||
CNetAddr source = CNetAddr("252.2.2.2:8333");
|
||||
CNetAddr source = CNetAddr("252.2.2.2");
|
||||
|
||||
BOOST_CHECK(addrman.size() == 0);
|
||||
|
||||
for (unsigned int i = 1; i < 4; i++){
|
||||
CService addr = CService("250.1.1."+boost::to_string(i));
|
||||
for (unsigned int i = 1; i < 18; i++) {
|
||||
CService addr = CService("250.1.1." + boost::to_string(i));
|
||||
addrman.Add(CAddress(addr), source);
|
||||
|
||||
//Test 11: No collision in new table yet.
|
||||
//Test 13: No collision in new table yet.
|
||||
BOOST_CHECK(addrman.size() == i);
|
||||
}
|
||||
|
||||
//Test 12: new table collision!
|
||||
CService addr1 = CService("250.1.1.4");
|
||||
//Test 14: new table collision!
|
||||
CService addr1 = CService("250.1.1.18");
|
||||
addrman.Add(CAddress(addr1), source);
|
||||
BOOST_CHECK(addrman.size() == 3);
|
||||
BOOST_CHECK(addrman.size() == 17);
|
||||
|
||||
CService addr2 = CService("250.1.1.5");
|
||||
CService addr2 = CService("250.1.1.19");
|
||||
addrman.Add(CAddress(addr2), source);
|
||||
BOOST_CHECK(addrman.size() == 4);
|
||||
BOOST_CHECK(addrman.size() == 18);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(addrman_tried_collisions)
|
||||
@@ -152,29 +222,300 @@ BOOST_AUTO_TEST_CASE(addrman_tried_collisions)
|
||||
// Set addrman addr placement to be deterministic.
|
||||
addrman.MakeDeterministic();
|
||||
|
||||
CNetAddr source = CNetAddr("252.2.2.2:8333");
|
||||
CNetAddr source = CNetAddr("252.2.2.2");
|
||||
|
||||
BOOST_CHECK(addrman.size() == 0);
|
||||
|
||||
for (unsigned int i = 1; i < 75; i++){
|
||||
CService addr = CService("250.1.1."+boost::to_string(i));
|
||||
for (unsigned int i = 1; i < 80; i++) {
|
||||
CService addr = CService("250.1.1." + boost::to_string(i));
|
||||
addrman.Add(CAddress(addr), source);
|
||||
addrman.Good(CAddress(addr));
|
||||
|
||||
//Test 13: No collision in tried table yet.
|
||||
//Test 15: No collision in tried table yet.
|
||||
BOOST_TEST_MESSAGE(addrman.size());
|
||||
BOOST_CHECK(addrman.size() == i);
|
||||
}
|
||||
|
||||
//Test 14: tried table collision!
|
||||
CService addr1 = CService("250.1.1.76");
|
||||
//Test 16: tried table collision!
|
||||
CService addr1 = CService("250.1.1.80");
|
||||
addrman.Add(CAddress(addr1), source);
|
||||
BOOST_CHECK(addrman.size() == 74);
|
||||
BOOST_CHECK(addrman.size() == 79);
|
||||
|
||||
CService addr2 = CService("250.1.1.77");
|
||||
CService addr2 = CService("250.1.1.81");
|
||||
addrman.Add(CAddress(addr2), source);
|
||||
BOOST_CHECK(addrman.size() == 75);
|
||||
BOOST_CHECK(addrman.size() == 80);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(addrman_find)
|
||||
{
|
||||
CAddrManTest addrman;
|
||||
|
||||
// Set addrman addr placement to be deterministic.
|
||||
addrman.MakeDeterministic();
|
||||
|
||||
BOOST_CHECK(addrman.size() == 0);
|
||||
|
||||
CAddress addr1 = CAddress(CService("250.1.2.1", 8333));
|
||||
CAddress addr2 = CAddress(CService("250.1.2.1", 9999));
|
||||
CAddress addr3 = CAddress(CService("251.255.2.1", 8333));
|
||||
|
||||
CNetAddr source1 = CNetAddr("250.1.2.1");
|
||||
CNetAddr source2 = CNetAddr("250.1.2.2");
|
||||
|
||||
addrman.Add(addr1, source1);
|
||||
addrman.Add(addr2, source2);
|
||||
addrman.Add(addr3, source1);
|
||||
|
||||
// Test 17: 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");
|
||||
|
||||
// Test 18; Find does not discriminate by port number.
|
||||
CAddrInfo* info2 = addrman.Find(addr2);
|
||||
BOOST_CHECK(info2);
|
||||
if (info2)
|
||||
BOOST_CHECK(info2->ToString() == info1->ToString());
|
||||
|
||||
// Test 19: 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_AUTO_TEST_CASE(addrman_create)
|
||||
{
|
||||
CAddrManTest addrman;
|
||||
|
||||
// Set addrman addr placement to be deterministic.
|
||||
addrman.MakeDeterministic();
|
||||
|
||||
BOOST_CHECK(addrman.size() == 0);
|
||||
|
||||
CAddress addr1 = CAddress(CService("250.1.2.1", 8333));
|
||||
CNetAddr source1 = CNetAddr("250.1.2.1");
|
||||
|
||||
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");
|
||||
|
||||
CAddrInfo* info2 = addrman.Find(addr1);
|
||||
BOOST_CHECK(info2->ToString() == "250.1.2.1:8333");
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(addrman_delete)
|
||||
{
|
||||
CAddrManTest addrman;
|
||||
|
||||
// Set addrman addr placement to be deterministic.
|
||||
addrman.MakeDeterministic();
|
||||
|
||||
BOOST_CHECK(addrman.size() == 0);
|
||||
|
||||
CAddress addr1 = CAddress(CService("250.1.2.1", 8333));
|
||||
CNetAddr source1 = CNetAddr("250.1.2.1");
|
||||
|
||||
int nId;
|
||||
addrman.Create(addr1, source1, &nId);
|
||||
|
||||
// Test 21: Delete should actually delete the addr.
|
||||
BOOST_CHECK(addrman.size() == 1);
|
||||
addrman.Delete(nId);
|
||||
BOOST_CHECK(addrman.size() == 0);
|
||||
CAddrInfo* info2 = addrman.Find(addr1);
|
||||
BOOST_CHECK(info2 == NULL);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(addrman_getaddr)
|
||||
{
|
||||
CAddrManTest addrman;
|
||||
|
||||
// Set addrman addr placement to be deterministic.
|
||||
addrman.MakeDeterministic();
|
||||
|
||||
// Test 22: Sanity check, GetAddr should never return anything if addrman
|
||||
// is empty.
|
||||
BOOST_CHECK(addrman.size() == 0);
|
||||
vector<CAddress> vAddr1 = addrman.GetAddr();
|
||||
BOOST_CHECK(vAddr1.size() == 0);
|
||||
|
||||
CAddress addr1 = CAddress(CService("250.250.2.1", 8333));
|
||||
addr1.nTime = GetAdjustedTime(); // Set time so isTerrible = false
|
||||
CAddress addr2 = CAddress(CService("250.251.2.2", 9999));
|
||||
addr2.nTime = GetAdjustedTime();
|
||||
CAddress addr3 = CAddress(CService("251.252.2.3", 8333));
|
||||
addr3.nTime = GetAdjustedTime();
|
||||
CAddress addr4 = CAddress(CService("252.253.3.4", 8333));
|
||||
addr4.nTime = GetAdjustedTime();
|
||||
CAddress addr5 = CAddress(CService("252.254.4.5", 8333));
|
||||
addr5.nTime = GetAdjustedTime();
|
||||
CNetAddr source1 = CNetAddr("250.1.2.1");
|
||||
CNetAddr source2 = CNetAddr("250.2.3.3");
|
||||
|
||||
// Test 23: Ensure GetAddr works with new addresses.
|
||||
addrman.Add(addr1, source1);
|
||||
addrman.Add(addr2, source2);
|
||||
addrman.Add(addr3, source1);
|
||||
addrman.Add(addr4, source2);
|
||||
addrman.Add(addr5, source1);
|
||||
|
||||
// GetAddr returns 23% of addresses, 23% of 5 is 1 rounded down.
|
||||
BOOST_CHECK(addrman.GetAddr().size() == 1);
|
||||
|
||||
// Test 24: Ensure GetAddr works with new and tried addresses.
|
||||
addrman.Good(CAddress(addr1));
|
||||
addrman.Good(CAddress(addr2));
|
||||
BOOST_CHECK(addrman.GetAddr().size() == 1);
|
||||
|
||||
// Test 25: 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;
|
||||
string strAddr = boost::to_string(octet1) + "." + boost::to_string(octet2) + "." + boost::to_string(octet3) + ".23";
|
||||
CAddress addr = CAddress(CService(strAddr));
|
||||
|
||||
// Ensure that for all addrs in addrman, isTerrible == false.
|
||||
addr.nTime = GetAdjustedTime();
|
||||
addrman.Add(addr, CNetAddr(strAddr));
|
||||
if (i % 8 == 0)
|
||||
addrman.Good(addr);
|
||||
}
|
||||
vector<CAddress> vAddr = addrman.GetAddr();
|
||||
|
||||
size_t percent23 = (addrman.size() * 23) / 100;
|
||||
BOOST_CHECK(vAddr.size() == percent23);
|
||||
BOOST_CHECK(vAddr.size() == 461);
|
||||
// (Addrman.size() < number of addresses added) due to address collisons.
|
||||
BOOST_CHECK(addrman.size() == 2007);
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket)
|
||||
{
|
||||
CAddrManTest addrman;
|
||||
|
||||
// Set addrman addr placement to be deterministic.
|
||||
addrman.MakeDeterministic();
|
||||
|
||||
CAddress addr1 = CAddress(CService("250.1.1.1", 8333));
|
||||
CAddress addr2 = CAddress(CService("250.1.1.1", 9999));
|
||||
|
||||
CNetAddr source1 = CNetAddr("250.1.1.1");
|
||||
|
||||
|
||||
CAddrInfo info1 = CAddrInfo(addr1, source1);
|
||||
|
||||
uint256 nKey1 = (uint256)(CHashWriter(SER_GETHASH, 0) << 1).GetHash();
|
||||
uint256 nKey2 = (uint256)(CHashWriter(SER_GETHASH, 0) << 2).GetHash();
|
||||
|
||||
|
||||
BOOST_CHECK(info1.GetTriedBucket(nKey1) == 40);
|
||||
|
||||
// Test 26: 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
|
||||
// different buckets because they have different keys.
|
||||
CAddrInfo info2 = CAddrInfo(addr2, source1);
|
||||
|
||||
BOOST_CHECK(info1.GetKey() != info2.GetKey());
|
||||
BOOST_CHECK(info1.GetTriedBucket(nKey1) != info2.GetTriedBucket(nKey1));
|
||||
|
||||
set<int> buckets;
|
||||
for (int i = 0; i < 255; i++) {
|
||||
CAddrInfo infoi = CAddrInfo(
|
||||
CAddress(CService("250.1.1." + boost::to_string(i))),
|
||||
CNetAddr("250.1.1." + boost::to_string(i)));
|
||||
int bucket = infoi.GetTriedBucket(nKey1);
|
||||
buckets.insert(bucket);
|
||||
}
|
||||
// Test 28: IP addresses in the same group (\16 prefix for IPv4) should
|
||||
// never get more than 8 buckets
|
||||
BOOST_CHECK(buckets.size() == 8);
|
||||
|
||||
buckets.clear();
|
||||
for (int j = 0; j < 255; j++) {
|
||||
CAddrInfo infoj = CAddrInfo(
|
||||
CAddress(CService("250." + boost::to_string(j) + ".1.1")),
|
||||
CNetAddr("250." + boost::to_string(j) + ".1.1"));
|
||||
int bucket = infoj.GetTriedBucket(nKey1);
|
||||
buckets.insert(bucket);
|
||||
}
|
||||
// Test 29: IP addresses in the different groups should map to more than
|
||||
// 8 buckets.
|
||||
BOOST_CHECK(buckets.size() == 160);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket)
|
||||
{
|
||||
CAddrManTest addrman;
|
||||
|
||||
// Set addrman addr placement to be deterministic.
|
||||
addrman.MakeDeterministic();
|
||||
|
||||
CAddress addr1 = CAddress(CService("250.1.2.1", 8333));
|
||||
CAddress addr2 = CAddress(CService("250.1.2.1", 9999));
|
||||
|
||||
CNetAddr source1 = CNetAddr("250.1.2.1");
|
||||
|
||||
CAddrInfo info1 = CAddrInfo(addr1, source1);
|
||||
|
||||
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 30: 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
|
||||
CAddrInfo info2 = CAddrInfo(addr2, source1);
|
||||
BOOST_CHECK(info1.GetKey() != info2.GetKey());
|
||||
BOOST_CHECK(info1.GetNewBucket(nKey1) == info2.GetNewBucket(nKey1));
|
||||
|
||||
set<int> buckets;
|
||||
for (int i = 0; i < 255; i++) {
|
||||
CAddrInfo infoi = CAddrInfo(
|
||||
CAddress(CService("250.1.1." + boost::to_string(i))),
|
||||
CNetAddr("250.1.1." + boost::to_string(i)));
|
||||
int bucket = infoi.GetNewBucket(nKey1);
|
||||
buckets.insert(bucket);
|
||||
}
|
||||
// Test 32: IP addresses in the same group (\16 prefix for IPv4) should
|
||||
// always map to the same bucket.
|
||||
BOOST_CHECK(buckets.size() == 1);
|
||||
|
||||
buckets.clear();
|
||||
for (int j = 0; j < 4 * 255; j++) {
|
||||
CAddrInfo infoj = CAddrInfo(CAddress(
|
||||
CService(
|
||||
boost::to_string(250 + (j / 255)) + "." + boost::to_string(j % 256) + ".1.1")),
|
||||
CNetAddr("251.4.1.1"));
|
||||
int bucket = infoj.GetNewBucket(nKey1);
|
||||
buckets.insert(bucket);
|
||||
}
|
||||
// Test 33: IP addresses in the same source groups should map to no more
|
||||
// than 64 buckets.
|
||||
BOOST_CHECK(buckets.size() <= 64);
|
||||
|
||||
buckets.clear();
|
||||
for (int p = 0; p < 255; p++) {
|
||||
CAddrInfo infoj = CAddrInfo(
|
||||
CAddress(CService("250.1.1.1")),
|
||||
CNetAddr("250." + boost::to_string(p) + ".1.1"));
|
||||
int bucket = infoj.GetNewBucket(nKey1);
|
||||
buckets.insert(bucket);
|
||||
}
|
||||
// Test 34: IP addresses in the different source groups should map to more
|
||||
// than 64 buckets.
|
||||
BOOST_CHECK(buckets.size() > 64);
|
||||
}
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013 The Bitcoin Core developers
|
||||
// Copyright (c) 2013-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2013 The Bitcoin Core developers
|
||||
// Copyright (c) 2012-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2011-2013 The Bitcoin Core developers
|
||||
// Copyright (c) 2011-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2013 The Bitcoin Core developers
|
||||
// Copyright (c) 2012-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2011-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2011-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2011-2013 The Bitcoin Core developers
|
||||
// Copyright (c) 2011-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -1,180 +0,0 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2013 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_BIGNUM_H
|
||||
#define BITCOIN_TEST_BIGNUM_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
class bignum_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
explicit bignum_error(const std::string& str) : std::runtime_error(str) {}
|
||||
};
|
||||
|
||||
|
||||
/** C++ wrapper for BIGNUM (OpenSSL bignum) */
|
||||
class CBigNum : public BIGNUM
|
||||
{
|
||||
public:
|
||||
CBigNum()
|
||||
{
|
||||
BN_init(this);
|
||||
}
|
||||
|
||||
CBigNum(const CBigNum& b)
|
||||
{
|
||||
BN_init(this);
|
||||
if (!BN_copy(this, &b))
|
||||
{
|
||||
BN_clear_free(this);
|
||||
throw bignum_error("CBigNum::CBigNum(const CBigNum&): BN_copy failed");
|
||||
}
|
||||
}
|
||||
|
||||
CBigNum& operator=(const CBigNum& b)
|
||||
{
|
||||
if (!BN_copy(this, &b))
|
||||
throw bignum_error("CBigNum::operator=: BN_copy failed");
|
||||
return (*this);
|
||||
}
|
||||
|
||||
~CBigNum()
|
||||
{
|
||||
BN_clear_free(this);
|
||||
}
|
||||
|
||||
CBigNum(long long n) { BN_init(this); setint64(n); }
|
||||
|
||||
explicit CBigNum(const std::vector<unsigned char>& vch)
|
||||
{
|
||||
BN_init(this);
|
||||
setvch(vch);
|
||||
}
|
||||
|
||||
int getint() const
|
||||
{
|
||||
BN_ULONG n = BN_get_word(this);
|
||||
if (!BN_is_negative(this))
|
||||
return (n > (BN_ULONG)std::numeric_limits<int>::max() ? std::numeric_limits<int>::max() : n);
|
||||
else
|
||||
return (n > (BN_ULONG)std::numeric_limits<int>::max() ? std::numeric_limits<int>::min() : -(int)n);
|
||||
}
|
||||
|
||||
void setint64(int64_t sn)
|
||||
{
|
||||
unsigned char pch[sizeof(sn) + 6];
|
||||
unsigned char* p = pch + 4;
|
||||
bool fNegative;
|
||||
uint64_t n;
|
||||
|
||||
if (sn < (int64_t)0)
|
||||
{
|
||||
// Since the minimum signed integer cannot be represented as positive so long as its type is signed,
|
||||
// and it's not well-defined what happens if you make it unsigned before negating it,
|
||||
// we instead increment the negative integer by 1, convert it, then increment the (now positive) unsigned integer by 1 to compensate
|
||||
n = -(sn + 1);
|
||||
++n;
|
||||
fNegative = true;
|
||||
} else {
|
||||
n = sn;
|
||||
fNegative = false;
|
||||
}
|
||||
|
||||
bool fLeadingZeroes = true;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
unsigned char c = (n >> 56) & 0xff;
|
||||
n <<= 8;
|
||||
if (fLeadingZeroes)
|
||||
{
|
||||
if (c == 0)
|
||||
continue;
|
||||
if (c & 0x80)
|
||||
*p++ = (fNegative ? 0x80 : 0);
|
||||
else if (fNegative)
|
||||
c |= 0x80;
|
||||
fLeadingZeroes = false;
|
||||
}
|
||||
*p++ = c;
|
||||
}
|
||||
unsigned int nSize = p - (pch + 4);
|
||||
pch[0] = (nSize >> 24) & 0xff;
|
||||
pch[1] = (nSize >> 16) & 0xff;
|
||||
pch[2] = (nSize >> 8) & 0xff;
|
||||
pch[3] = (nSize) & 0xff;
|
||||
BN_mpi2bn(pch, p - pch, this);
|
||||
}
|
||||
|
||||
void setvch(const std::vector<unsigned char>& vch)
|
||||
{
|
||||
std::vector<unsigned char> vch2(vch.size() + 4);
|
||||
unsigned int nSize = vch.size();
|
||||
// BIGNUM's byte stream format expects 4 bytes of
|
||||
// big endian size data info at the front
|
||||
vch2[0] = (nSize >> 24) & 0xff;
|
||||
vch2[1] = (nSize >> 16) & 0xff;
|
||||
vch2[2] = (nSize >> 8) & 0xff;
|
||||
vch2[3] = (nSize >> 0) & 0xff;
|
||||
// swap data to big endian
|
||||
reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4);
|
||||
BN_mpi2bn(&vch2[0], vch2.size(), this);
|
||||
}
|
||||
|
||||
std::vector<unsigned char> getvch() const
|
||||
{
|
||||
unsigned int nSize = BN_bn2mpi(this, NULL);
|
||||
if (nSize <= 4)
|
||||
return std::vector<unsigned char>();
|
||||
std::vector<unsigned char> vch(nSize);
|
||||
BN_bn2mpi(this, &vch[0]);
|
||||
vch.erase(vch.begin(), vch.begin() + 4);
|
||||
reverse(vch.begin(), vch.end());
|
||||
return vch;
|
||||
}
|
||||
|
||||
friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b);
|
||||
};
|
||||
|
||||
|
||||
|
||||
inline const CBigNum operator+(const CBigNum& a, const CBigNum& b)
|
||||
{
|
||||
CBigNum r;
|
||||
if (!BN_add(&r, &a, &b))
|
||||
throw bignum_error("CBigNum::operator+: BN_add failed");
|
||||
return r;
|
||||
}
|
||||
|
||||
inline const CBigNum operator-(const CBigNum& a, const CBigNum& b)
|
||||
{
|
||||
CBigNum r;
|
||||
if (!BN_sub(&r, &a, &b))
|
||||
throw bignum_error("CBigNum::operator-: BN_sub failed");
|
||||
return r;
|
||||
}
|
||||
|
||||
inline const CBigNum operator-(const CBigNum& a)
|
||||
{
|
||||
CBigNum r(a);
|
||||
BN_set_negative(&r, !BN_is_negative(&r));
|
||||
return r;
|
||||
}
|
||||
|
||||
inline bool operator==(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) == 0); }
|
||||
inline bool operator!=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) != 0); }
|
||||
inline bool operator<=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) <= 0); }
|
||||
inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) >= 0); }
|
||||
inline bool operator<(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) < 0); }
|
||||
inline bool operator>(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) > 0); }
|
||||
|
||||
#endif // BITCOIN_TEST_BIGNUM_H
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013 The Bitcoin Core developers
|
||||
// Copyright (c) 2013-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2013 The Bitcoin Core developers
|
||||
// Copyright (c) 2012-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2013-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2014-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -164,14 +164,23 @@ BOOST_AUTO_TEST_CASE(coins_cache_simulation_test)
|
||||
}
|
||||
}
|
||||
|
||||
if (insecure_rand() % 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);
|
||||
stack[flushIndex]->Flush();
|
||||
}
|
||||
}
|
||||
if (insecure_rand() % 100 == 0) {
|
||||
// Every 100 iterations, change the cache stack.
|
||||
if (stack.size() > 0 && insecure_rand() % 2 == 0) {
|
||||
//Remove the top cache
|
||||
stack.back()->Flush();
|
||||
delete stack.back();
|
||||
stack.pop_back();
|
||||
}
|
||||
if (stack.size() == 0 || (stack.size() < 4 && insecure_rand() % 2)) {
|
||||
//Add a new cache
|
||||
CCoinsView* tip = &base;
|
||||
if (stack.size() > 0) {
|
||||
tip = stack.back();
|
||||
@@ -304,6 +313,13 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test)
|
||||
}
|
||||
}
|
||||
|
||||
if (insecure_rand() % 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);
|
||||
stack[flushIndex]->Flush();
|
||||
}
|
||||
}
|
||||
if (insecure_rand() % 100 == 0) {
|
||||
// Every 100 iterations, change the cache stack.
|
||||
if (stack.size() > 0 && insecure_rand() % 2 == 0) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2013 The Bitcoin Core developers
|
||||
// Copyright (c) 2012-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2014-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -160,12 +160,12 @@
|
||||
["2 2 LSHIFT", "8 EQUAL", "P2SH,STRICTENC", "disabled"],
|
||||
["2 1 RSHIFT", "1 EQUAL", "P2SH,STRICTENC", "disabled"],
|
||||
|
||||
["1","NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC"],
|
||||
["'NOP_1_to_10' NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC"],
|
||||
["1","NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC"],
|
||||
["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC"],
|
||||
|
||||
["Ensure 100% coverage of discouraged NOPS"],
|
||||
["1", "NOP1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
|
||||
["1", "NOP2", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
|
||||
["1", "CHECKLOCKTIMEVERIFY", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
|
||||
["1", "NOP3", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
|
||||
["1", "NOP4", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
|
||||
["1", "NOP5", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"],
|
||||
|
||||
@@ -232,8 +232,8 @@
|
||||
["'abcdefghijklmnopqrstuvwxyz'", "HASH256 0x4c 0x20 0xca139bc10c2f660da42666f72e89a225936fc60f193c161124a672050c434671 EQUAL", "P2SH,STRICTENC"],
|
||||
|
||||
|
||||
["1","NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 1 EQUAL", "P2SH,STRICTENC"],
|
||||
["'NOP_1_to_10' NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_10' EQUAL", "P2SH,STRICTENC"],
|
||||
["1","NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 1 EQUAL", "P2SH,STRICTENC"],
|
||||
["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_10' EQUAL", "P2SH,STRICTENC"],
|
||||
|
||||
["1", "NOP", "P2SH,STRICTENC,DISCOURAGE_UPGRADABLE_NOPS", "Discourage NOPx flag allows OP_NOP"],
|
||||
|
||||
@@ -442,7 +442,7 @@
|
||||
["NOP", "CODESEPARATOR 1", "P2SH,STRICTENC"],
|
||||
|
||||
["NOP", "NOP1 1", "P2SH,STRICTENC"],
|
||||
["NOP", "NOP2 1", "P2SH,STRICTENC"],
|
||||
["NOP", "CHECKLOCKTIMEVERIFY 1", "P2SH,STRICTENC"],
|
||||
["NOP", "NOP3 1", "P2SH,STRICTENC"],
|
||||
["NOP", "NOP4 1", "P2SH,STRICTENC"],
|
||||
["NOP", "NOP5 1", "P2SH,STRICTENC"],
|
||||
|
||||
@@ -127,66 +127,66 @@
|
||||
["CHECKLOCKTIMEVERIFY tests"],
|
||||
|
||||
["By-height locks, with argument just beyond tx nLockTime"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1 NOP2 1"]],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1 CHECKLOCKTIMEVERIFY 1"]],
|
||||
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 CHECKLOCKTIMEVERIFY 1"]],
|
||||
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000fe64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
|
||||
["By-time locks, with argument just beyond tx nLockTime (but within numerical boundaries)"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000001 NOP2 1"]],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000001 CHECKLOCKTIMEVERIFY 1"]],
|
||||
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP2 1"]],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 CHECKLOCKTIMEVERIFY 1"]],
|
||||
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000feffffff", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
|
||||
["Argument missing"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "NOP2 1"]],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "CHECKLOCKTIMEVERIFY 1"]],
|
||||
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]],
|
||||
"010000000100010000000000000000000000000000000000000000000000000000000000000000000001b1010000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
|
||||
["Argument negative with by-blockheight nLockTime=0"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 NOP2 1"]],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 CHECKLOCKTIMEVERIFY 1"]],
|
||||
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
|
||||
["Argument negative with by-blocktime nLockTime=500,000,000"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 NOP2 1"]],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 CHECKLOCKTIMEVERIFY 1"]],
|
||||
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]],
|
||||
"010000000100010000000000000000000000000000000000000000000000000000000000000000000004005194b1010000000100000000000000000002000000", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
|
||||
["Input locked"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"]],
|
||||
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0"]],
|
||||
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000251b1ffffffff0100000000000000000002000000", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
|
||||
["Another input being unlocked isn't sufficient; the CHECKLOCKTIMEVERIFY-using input must be unlocked"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"] ,
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"] ,
|
||||
["0000000000000000000000000000000000000000000000000000000000000200", 1, "1"]],
|
||||
"010000000200010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00020000000000000000000000000000000000000000000000000000000000000100000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
|
||||
["Argument/tx height/time mismatch, both versions"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"]],
|
||||
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0"]],
|
||||
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000251b100000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 CHECKLOCKTIMEVERIFY 1"]],
|
||||
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 CHECKLOCKTIMEVERIFY 1"]],
|
||||
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 CHECKLOCKTIMEVERIFY 1"]],
|
||||
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
|
||||
["Argument 2^32 with nLockTime=2^32-1"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967296 NOP2 1"]],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967296 CHECKLOCKTIMEVERIFY 1"]],
|
||||
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffffff", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
|
||||
["Same, but with nLockTime=2^31-1"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 NOP2 1"]],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 CHECKLOCKTIMEVERIFY 1"]],
|
||||
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffff7f", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
|
||||
["6 byte non-minimally-encoded arguments are invalid even if their contents are valid"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x06 0x000000000000 NOP2 1"]],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x06 0x000000000000 CHECKLOCKTIMEVERIFY 1"]],
|
||||
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
|
||||
["Failure due to failing CHECKLOCKTIMEVERIFY in scriptSig"],
|
||||
|
||||
@@ -190,35 +190,35 @@
|
||||
["CHECKLOCKTIMEVERIFY tests"],
|
||||
|
||||
["By-height locks, with argument == 0 and == tx nLockTime"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"]],
|
||||
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 CHECKLOCKTIMEVERIFY 1"]],
|
||||
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"]],
|
||||
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
|
||||
["By-time locks, with argument just beyond tx nLockTime (but within numerical boundaries)"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 CHECKLOCKTIMEVERIFY 1"]],
|
||||
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP2 1"]],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 CHECKLOCKTIMEVERIFY 1"]],
|
||||
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffffff", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 CHECKLOCKTIMEVERIFY 1"]],
|
||||
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffffff", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
|
||||
["Any non-maxint nSequence is fine"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"]],
|
||||
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000feffffff0100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
|
||||
["The argument can be calculated rather than created directly by a PUSHDATA"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 1ADD NOP2 1"]],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 1ADD CHECKLOCKTIMEVERIFY 1"]],
|
||||
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
|
||||
["Perhaps even by an ADD producing a 5-byte result that is out of bounds for other opcodes"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483647 2147483647 ADD NOP2 1"]],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483647 2147483647 ADD CHECKLOCKTIMEVERIFY 1"]],
|
||||
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000feffffff", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
|
||||
["5 byte non-minimally-encoded arguments are valid"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x05 0x0000000000 NOP2 1"]],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x05 0x0000000000 CHECKLOCKTIMEVERIFY 1"]],
|
||||
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
|
||||
|
||||
["Valid CHECKLOCKTIMEVERIFY in scriptSig"],
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2013 The Bitcoin Core developers
|
||||
// Copyright (c) 2012-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2013 The Bitcoin Core developers
|
||||
// Copyright (c) 2012-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013 The Bitcoin Core developers
|
||||
// Copyright (c) 2013-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2013 The Bitcoin Core developers
|
||||
// Copyright (c) 2012-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2014-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -72,5 +72,4 @@ BOOST_AUTO_TEST_CASE(test_combiner_all)
|
||||
Test.disconnect(&ReturnTrue);
|
||||
BOOST_CHECK(Test());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2011-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2011-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -102,12 +102,13 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest)
|
||||
removed.clear();
|
||||
}
|
||||
|
||||
template<int index>
|
||||
void CheckSort(CTxMemPool &pool, std::vector<std::string> &sortedOrder)
|
||||
{
|
||||
BOOST_CHECK_EQUAL(pool.size(), sortedOrder.size());
|
||||
CTxMemPool::indexed_transaction_set::nth_index<1>::type::iterator it = pool.mapTx.get<1>().begin();
|
||||
typename CTxMemPool::indexed_transaction_set::nth_index<index>::type::iterator it = pool.mapTx.get<index>().begin();
|
||||
int count=0;
|
||||
for (; it != pool.mapTx.get<1>().end(); ++it, ++count) {
|
||||
for (; it != pool.mapTx.get<index>().end(); ++it, ++count) {
|
||||
BOOST_CHECK_EQUAL(it->GetTx().GetHash().ToString(), sortedOrder[count]);
|
||||
}
|
||||
}
|
||||
@@ -163,7 +164,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest)
|
||||
sortedOrder[2] = tx1.GetHash().ToString(); // 10000
|
||||
sortedOrder[3] = tx4.GetHash().ToString(); // 15000
|
||||
sortedOrder[4] = tx2.GetHash().ToString(); // 20000
|
||||
CheckSort(pool, sortedOrder);
|
||||
CheckSort<1>(pool, sortedOrder);
|
||||
|
||||
/* low fee but with high fee child */
|
||||
/* tx6 -> tx7 -> tx8, tx9 -> tx10 */
|
||||
@@ -175,7 +176,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest)
|
||||
BOOST_CHECK_EQUAL(pool.size(), 6);
|
||||
// Check that at this point, tx6 is sorted low
|
||||
sortedOrder.insert(sortedOrder.begin(), tx6.GetHash().ToString());
|
||||
CheckSort(pool, sortedOrder);
|
||||
CheckSort<1>(pool, sortedOrder);
|
||||
|
||||
CTxMemPool::setEntries setAncestors;
|
||||
setAncestors.insert(pool.mapTx.find(tx6.GetHash()));
|
||||
@@ -201,7 +202,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest)
|
||||
sortedOrder.erase(sortedOrder.begin());
|
||||
sortedOrder.push_back(tx6.GetHash().ToString());
|
||||
sortedOrder.push_back(tx7.GetHash().ToString());
|
||||
CheckSort(pool, sortedOrder);
|
||||
CheckSort<1>(pool, sortedOrder);
|
||||
|
||||
/* low fee child of tx7 */
|
||||
CMutableTransaction tx8 = CMutableTransaction();
|
||||
@@ -216,7 +217,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest)
|
||||
|
||||
// Now tx8 should be sorted low, but tx6/tx both high
|
||||
sortedOrder.insert(sortedOrder.begin(), tx8.GetHash().ToString());
|
||||
CheckSort(pool, sortedOrder);
|
||||
CheckSort<1>(pool, sortedOrder);
|
||||
|
||||
/* low fee child of tx7 */
|
||||
CMutableTransaction tx9 = CMutableTransaction();
|
||||
@@ -231,7 +232,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest)
|
||||
// tx9 should be sorted low
|
||||
BOOST_CHECK_EQUAL(pool.size(), 9);
|
||||
sortedOrder.insert(sortedOrder.begin(), tx9.GetHash().ToString());
|
||||
CheckSort(pool, sortedOrder);
|
||||
CheckSort<1>(pool, sortedOrder);
|
||||
|
||||
std::vector<std::string> snapshotOrder = sortedOrder;
|
||||
|
||||
@@ -273,7 +274,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest)
|
||||
sortedOrder.insert(sortedOrder.begin()+5, tx9.GetHash().ToString());
|
||||
sortedOrder.insert(sortedOrder.begin()+6, tx8.GetHash().ToString());
|
||||
sortedOrder.insert(sortedOrder.begin()+7, tx10.GetHash().ToString()); // tx10 is just before tx6
|
||||
CheckSort(pool, sortedOrder);
|
||||
CheckSort<1>(pool, sortedOrder);
|
||||
|
||||
// there should be 10 transactions in the mempool
|
||||
BOOST_CHECK_EQUAL(pool.size(), 10);
|
||||
@@ -281,9 +282,42 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest)
|
||||
// Now try removing tx10 and verify the sort order returns to normal
|
||||
std::list<CTransaction> removed;
|
||||
pool.remove(pool.mapTx.find(tx10.GetHash())->GetTx(), removed, true);
|
||||
CheckSort(pool, snapshotOrder);
|
||||
CheckSort<1>(pool, snapshotOrder);
|
||||
|
||||
pool.remove(pool.mapTx.find(tx9.GetHash())->GetTx(), removed, true);
|
||||
pool.remove(pool.mapTx.find(tx8.GetHash())->GetTx(), removed, true);
|
||||
/* Now check the sort on the mining score index.
|
||||
* Final order should be:
|
||||
*
|
||||
* tx7 (2M)
|
||||
* tx2 (20k)
|
||||
* tx4 (15000)
|
||||
* tx1/tx5 (10000)
|
||||
* tx3/6 (0)
|
||||
* (Ties resolved by hash)
|
||||
*/
|
||||
sortedOrder.clear();
|
||||
sortedOrder.push_back(tx7.GetHash().ToString());
|
||||
sortedOrder.push_back(tx2.GetHash().ToString());
|
||||
sortedOrder.push_back(tx4.GetHash().ToString());
|
||||
if (tx1.GetHash() < tx5.GetHash()) {
|
||||
sortedOrder.push_back(tx5.GetHash().ToString());
|
||||
sortedOrder.push_back(tx1.GetHash().ToString());
|
||||
} else {
|
||||
sortedOrder.push_back(tx1.GetHash().ToString());
|
||||
sortedOrder.push_back(tx5.GetHash().ToString());
|
||||
}
|
||||
if (tx3.GetHash() < tx6.GetHash()) {
|
||||
sortedOrder.push_back(tx6.GetHash().ToString());
|
||||
sortedOrder.push_back(tx3.GetHash().ToString());
|
||||
} else {
|
||||
sortedOrder.push_back(tx3.GetHash().ToString());
|
||||
sortedOrder.push_back(tx6.GetHash().ToString());
|
||||
}
|
||||
CheckSort<3>(pool, sortedOrder);
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest)
|
||||
{
|
||||
CTxMemPool pool(CFeeRate(1000));
|
||||
|
||||
136
src/test/merkle_tests.cpp
Normal file
136
src/test/merkle_tests.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
// Copyright (c) 2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "consensus/merkle.h"
|
||||
#include "test/test_bitcoin.h"
|
||||
#include "random.h"
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(merkle_tests, TestingSetup)
|
||||
|
||||
// Older version of the merkle root computation code, for comparison.
|
||||
static uint256 BlockBuildMerkleTree(const CBlock& block, bool* fMutated, std::vector<uint256>& vMerkleTree)
|
||||
{
|
||||
vMerkleTree.clear();
|
||||
vMerkleTree.reserve(block.vtx.size() * 2 + 16); // Safe upper bound for the number of total nodes.
|
||||
for (std::vector<CTransaction>::const_iterator it(block.vtx.begin()); it != block.vtx.end(); ++it)
|
||||
vMerkleTree.push_back(it->GetHash());
|
||||
int j = 0;
|
||||
bool mutated = false;
|
||||
for (int nSize = block.vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
|
||||
{
|
||||
for (int i = 0; i < nSize; i += 2)
|
||||
{
|
||||
int i2 = std::min(i+1, nSize-1);
|
||||
if (i2 == i + 1 && i2 + 1 == nSize && vMerkleTree[j+i] == vMerkleTree[j+i2]) {
|
||||
// Two identical hashes at the end of the list at a particular level.
|
||||
mutated = true;
|
||||
}
|
||||
vMerkleTree.push_back(Hash(vMerkleTree[j+i].begin(), vMerkleTree[j+i].end(),
|
||||
vMerkleTree[j+i2].begin(), vMerkleTree[j+i2].end()));
|
||||
}
|
||||
j += nSize;
|
||||
}
|
||||
if (fMutated) {
|
||||
*fMutated = mutated;
|
||||
}
|
||||
return (vMerkleTree.empty() ? uint256() : vMerkleTree.back());
|
||||
}
|
||||
|
||||
// Older version of the merkle branch computation code, for comparison.
|
||||
static std::vector<uint256> BlockGetMerkleBranch(const CBlock& block, const std::vector<uint256>& vMerkleTree, int nIndex)
|
||||
{
|
||||
std::vector<uint256> vMerkleBranch;
|
||||
int j = 0;
|
||||
for (int nSize = block.vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
|
||||
{
|
||||
int i = std::min(nIndex^1, nSize-1);
|
||||
vMerkleBranch.push_back(vMerkleTree[j+i]);
|
||||
nIndex >>= 1;
|
||||
j += nSize;
|
||||
}
|
||||
return vMerkleBranch;
|
||||
}
|
||||
|
||||
static inline int ctz(uint32_t i) {
|
||||
if (i == 0) return 0;
|
||||
int j = 0;
|
||||
while (!(i & 1)) {
|
||||
j++;
|
||||
i >>= 1;
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
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);
|
||||
// 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.
|
||||
if (duplicate1 >= ntx) break; // Duplication of the entire tree results in a different root (it adds a level).
|
||||
int ntx1 = ntx + duplicate1; // The resulting number of transactions after the first duplication.
|
||||
int duplicate2 = mutate >= 2 ? 1 << ctz(ntx1) : 0; // Likewise for the second mutation.
|
||||
if (duplicate2 >= ntx1) break;
|
||||
int ntx2 = ntx1 + duplicate2;
|
||||
int duplicate3 = mutate >= 3 ? 1 << ctz(ntx2) : 0; // And for the third mutation.
|
||||
if (duplicate3 >= ntx2) break;
|
||||
int ntx3 = ntx2 + duplicate3;
|
||||
// Build a block with ntx different transactions.
|
||||
CBlock block;
|
||||
block.vtx.resize(ntx);
|
||||
for (int j = 0; j < ntx; j++) {
|
||||
CMutableTransaction mtx;
|
||||
mtx.nLockTime = j;
|
||||
block.vtx[j] = mtx;
|
||||
}
|
||||
// Compute the root of the block before mutating it.
|
||||
bool unmutatedMutated = false;
|
||||
uint256 unmutatedRoot = BlockMerkleRoot(block, &unmutatedMutated);
|
||||
BOOST_CHECK(unmutatedMutated == false);
|
||||
// Optionally mutate by duplicating the last transactions, resulting in the same merkle root.
|
||||
block.vtx.resize(ntx3);
|
||||
for (int j = 0; j < duplicate1; j++) {
|
||||
block.vtx[ntx + j] = block.vtx[ntx + j - duplicate1];
|
||||
}
|
||||
for (int j = 0; j < duplicate2; j++) {
|
||||
block.vtx[ntx1 + j] = block.vtx[ntx1 + j - duplicate2];
|
||||
}
|
||||
for (int j = 0; j < duplicate3; j++) {
|
||||
block.vtx[ntx2 + j] = block.vtx[ntx2 + j - duplicate3];
|
||||
}
|
||||
// Compute the merkle root and merkle tree using the old mechanism.
|
||||
bool oldMutated = false;
|
||||
std::vector<uint256> merkleTree;
|
||||
uint256 oldRoot = BlockBuildMerkleTree(block, &oldMutated, merkleTree);
|
||||
// Compute the merkle root using the new mechanism.
|
||||
bool newMutated = false;
|
||||
uint256 newRoot = BlockMerkleRoot(block, &newMutated);
|
||||
BOOST_CHECK(oldRoot == newRoot);
|
||||
BOOST_CHECK(newRoot == unmutatedRoot);
|
||||
BOOST_CHECK((newRoot == uint256()) == (ntx == 0));
|
||||
BOOST_CHECK(oldMutated == newMutated);
|
||||
BOOST_CHECK(newMutated == !!mutate);
|
||||
// If no mutation was done (once for every ntx value), try up to 16 branches.
|
||||
if (mutate == 0) {
|
||||
for (int loop = 0; loop < std::min(ntx, 16); loop++) {
|
||||
// If ntx <= 16, try all branches. Otherise, try 16 random ones.
|
||||
int mtx = loop;
|
||||
if (ntx > 16) {
|
||||
mtx = insecure_rand() % ntx;
|
||||
}
|
||||
std::vector<uint256> newBranch = BlockMerkleBranch(block, mtx);
|
||||
std::vector<uint256> oldBranch = BlockGetMerkleBranch(block, merkleTree, mtx);
|
||||
BOOST_CHECK(oldBranch == newBranch);
|
||||
BOOST_CHECK(ComputeMerkleRootFromBranch(block.vtx[mtx].GetHash(), newBranch, mtx) == oldRoot);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
@@ -1,10 +1,11 @@
|
||||
// Copyright (c) 2011-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2011-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "chainparams.h"
|
||||
#include "coins.h"
|
||||
#include "consensus/consensus.h"
|
||||
#include "consensus/merkle.h"
|
||||
#include "consensus/validation.h"
|
||||
#include "main.h"
|
||||
#include "miner.h"
|
||||
@@ -93,7 +94,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
||||
pblock->vtx[0] = CTransaction(txCoinbase);
|
||||
if (txFirst.size() < 2)
|
||||
txFirst.push_back(new CTransaction(pblock->vtx[0]));
|
||||
pblock->hashMerkleRoot = pblock->ComputeMerkleRoot();
|
||||
pblock->hashMerkleRoot = BlockMerkleRoot(*pblock);
|
||||
pblock->nNonce = blockinfo[i].nonce;
|
||||
CValidationState state;
|
||||
BOOST_CHECK(ProcessNewBlock(state, chainparams, NULL, pblock, true, NULL));
|
||||
@@ -118,7 +119,23 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
||||
{
|
||||
tx.vout[0].nValue -= 1000000;
|
||||
hash = tx.GetHash();
|
||||
mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx));
|
||||
bool spendsCoinbase = (i == 0) ? true : false; // 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(1000000).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx));
|
||||
tx.vin[0].prevout.hash = hash;
|
||||
}
|
||||
BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error);
|
||||
mempool.clear();
|
||||
|
||||
tx.vin[0].prevout.hash = txFirst[0]->GetHash();
|
||||
tx.vout[0].nValue = 5000000000LL;
|
||||
for (unsigned int i = 0; i < 1001; ++i)
|
||||
{
|
||||
tx.vout[0].nValue -= 1000000;
|
||||
hash = tx.GetHash();
|
||||
bool spendsCoinbase = (i == 0) ? true : false; // only first tx spends coinbase
|
||||
// If we do set the # of sig ops in the CTxMemPoolEntry, template creation passes
|
||||
mempool.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).SpendsCoinbase(spendsCoinbase).SigOps(20).FromTx(tx));
|
||||
tx.vin[0].prevout.hash = hash;
|
||||
}
|
||||
BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey));
|
||||
@@ -138,18 +155,18 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
||||
{
|
||||
tx.vout[0].nValue -= 10000000;
|
||||
hash = tx.GetHash();
|
||||
mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx));
|
||||
bool spendsCoinbase = (i == 0) ? true : false; // only first tx spends coinbase
|
||||
mempool.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx));
|
||||
tx.vin[0].prevout.hash = hash;
|
||||
}
|
||||
BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey));
|
||||
delete pblocktemplate;
|
||||
mempool.clear();
|
||||
|
||||
// orphan in mempool
|
||||
// orphan in mempool, template creation fails
|
||||
hash = tx.GetHash();
|
||||
mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx));
|
||||
BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey));
|
||||
delete pblocktemplate;
|
||||
mempool.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).FromTx(tx));
|
||||
BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error);
|
||||
mempool.clear();
|
||||
|
||||
// child with higher priority than parent
|
||||
@@ -157,7 +174,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
||||
tx.vin[0].prevout.hash = txFirst[1]->GetHash();
|
||||
tx.vout[0].nValue = 4900000000LL;
|
||||
hash = tx.GetHash();
|
||||
mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx));
|
||||
mempool.addUnchecked(hash, entry.Fee(100000000LL).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
|
||||
tx.vin[0].prevout.hash = hash;
|
||||
tx.vin.resize(2);
|
||||
tx.vin[1].scriptSig = CScript() << OP_1;
|
||||
@@ -165,23 +182,23 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
||||
tx.vin[1].prevout.n = 0;
|
||||
tx.vout[0].nValue = 5900000000LL;
|
||||
hash = tx.GetHash();
|
||||
mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx));
|
||||
mempool.addUnchecked(hash, entry.Fee(400000000LL).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
|
||||
BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey));
|
||||
delete pblocktemplate;
|
||||
mempool.clear();
|
||||
|
||||
// coinbase in mempool
|
||||
// coinbase in mempool, template creation fails
|
||||
tx.vin.resize(1);
|
||||
tx.vin[0].prevout.SetNull();
|
||||
tx.vin[0].scriptSig = CScript() << OP_0 << OP_1;
|
||||
tx.vout[0].nValue = 0;
|
||||
hash = tx.GetHash();
|
||||
mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx));
|
||||
BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey));
|
||||
delete pblocktemplate;
|
||||
// give it a fee so it'll get mined
|
||||
mempool.addUnchecked(hash, entry.Fee(100000).Time(GetTime()).SpendsCoinbase(false).FromTx(tx));
|
||||
BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error);
|
||||
mempool.clear();
|
||||
|
||||
// invalid (pre-p2sh) txn in mempool
|
||||
// invalid (pre-p2sh) txn in mempool, template creation fails
|
||||
tx.vin[0].prevout.hash = txFirst[0]->GetHash();
|
||||
tx.vin[0].prevout.n = 0;
|
||||
tx.vin[0].scriptSig = CScript() << OP_1;
|
||||
@@ -189,28 +206,26 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
||||
script = CScript() << OP_0;
|
||||
tx.vout[0].scriptPubKey = GetScriptForDestination(CScriptID(script));
|
||||
hash = tx.GetHash();
|
||||
mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx));
|
||||
mempool.addUnchecked(hash, entry.Fee(10000000L).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
|
||||
tx.vin[0].prevout.hash = hash;
|
||||
tx.vin[0].scriptSig = CScript() << (std::vector<unsigned char>)script;
|
||||
tx.vin[0].scriptSig = CScript() << std::vector<unsigned char>(script.begin(), script.end());
|
||||
tx.vout[0].nValue -= 1000000;
|
||||
hash = tx.GetHash();
|
||||
mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx));
|
||||
BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey));
|
||||
delete pblocktemplate;
|
||||
mempool.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).SpendsCoinbase(false).FromTx(tx));
|
||||
BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error);
|
||||
mempool.clear();
|
||||
|
||||
// double spend txn pair in mempool
|
||||
// double spend txn pair in mempool, template creation fails
|
||||
tx.vin[0].prevout.hash = txFirst[0]->GetHash();
|
||||
tx.vin[0].scriptSig = CScript() << OP_1;
|
||||
tx.vout[0].nValue = 4900000000LL;
|
||||
tx.vout[0].scriptPubKey = CScript() << OP_1;
|
||||
hash = tx.GetHash();
|
||||
mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx));
|
||||
mempool.addUnchecked(hash, entry.Fee(100000000L).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
|
||||
tx.vout[0].scriptPubKey = CScript() << OP_2;
|
||||
hash = tx.GetHash();
|
||||
mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx));
|
||||
BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey));
|
||||
delete pblocktemplate;
|
||||
mempool.addUnchecked(hash, entry.Fee(100000000L).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
|
||||
BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error);
|
||||
mempool.clear();
|
||||
|
||||
// subsidy changing
|
||||
@@ -234,7 +249,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
||||
tx.vout[0].scriptPubKey = CScript() << OP_1;
|
||||
tx.nLockTime = chainActive.Tip()->nHeight+1;
|
||||
hash = tx.GetHash();
|
||||
mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx));
|
||||
mempool.addUnchecked(hash, entry.Fee(100000000L).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
|
||||
BOOST_CHECK(!CheckFinalTx(tx, LOCKTIME_MEDIAN_TIME_PAST));
|
||||
|
||||
// time locked
|
||||
@@ -248,7 +263,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
||||
tx2.vout[0].scriptPubKey = CScript() << OP_1;
|
||||
tx2.nLockTime = chainActive.Tip()->GetMedianTimePast()+1;
|
||||
hash = tx2.GetHash();
|
||||
mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx2));
|
||||
mempool.addUnchecked(hash, entry.Fee(100000000L).Time(GetTime()).SpendsCoinbase(true).FromTx(tx2));
|
||||
BOOST_CHECK(!CheckFinalTx(tx2, LOCKTIME_MEDIAN_TIME_PAST));
|
||||
|
||||
BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey));
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
// Copyright (c) 2012-2013 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "mruset.h"
|
||||
|
||||
#include "random.h"
|
||||
#include "util.h"
|
||||
#include "test/test_bitcoin.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#define NUM_TESTS 16
|
||||
#define MAX_SIZE 100
|
||||
|
||||
using namespace std;
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(mruset_tests, BasicTestingSetup)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(mruset_test)
|
||||
{
|
||||
// The mruset being tested.
|
||||
mruset<int> mru(5000);
|
||||
|
||||
// Run the test 10 times.
|
||||
for (int test = 0; test < 10; test++) {
|
||||
// Reset mru.
|
||||
mru.clear();
|
||||
|
||||
// A deque + set to simulate the mruset.
|
||||
std::deque<int> rep;
|
||||
std::set<int> all;
|
||||
|
||||
// Insert 10000 random integers below 15000.
|
||||
for (int j=0; j<10000; j++) {
|
||||
int add = GetRandInt(15000);
|
||||
mru.insert(add);
|
||||
|
||||
// Add the number to rep/all as well.
|
||||
if (all.count(add) == 0) {
|
||||
all.insert(add);
|
||||
rep.push_back(add);
|
||||
if (all.size() == 5001) {
|
||||
all.erase(rep.front());
|
||||
rep.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
// Do a full comparison between mru and the simulated mru every 1000 and every 5001 elements.
|
||||
if (j % 1000 == 0 || j % 5001 == 0) {
|
||||
mruset<int> mru2 = mru; // Also try making a copy
|
||||
|
||||
// Check that all elements that should be in there, are in there.
|
||||
BOOST_FOREACH(int x, rep) {
|
||||
BOOST_CHECK(mru.count(x));
|
||||
BOOST_CHECK(mru2.count(x));
|
||||
}
|
||||
|
||||
// Check that all elements that are in there, should be in there.
|
||||
BOOST_FOREACH(int x, mru) {
|
||||
BOOST_CHECK(all.count(x));
|
||||
}
|
||||
|
||||
// Check that all elements that are in there, should be in there.
|
||||
BOOST_FOREACH(int x, mru2) {
|
||||
BOOST_CHECK(all.count(x));
|
||||
}
|
||||
|
||||
for (int t = 0; t < 10; t++) {
|
||||
int r = GetRandInt(15000);
|
||||
BOOST_CHECK(all.count(r) == mru.count(r));
|
||||
BOOST_CHECK(all.count(r) == mru2.count(r));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2011-2013 The Bitcoin Core developers
|
||||
// Copyright (c) 2011-2014 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2013 The Bitcoin Core developers
|
||||
// Copyright (c) 2012-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
// Copyright (c) 2012-2013 The Bitcoin Core developers
|
||||
// Copyright (c) 2012-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "consensus/merkle.h"
|
||||
#include "merkleblock.h"
|
||||
#include "serialize.h"
|
||||
#include "streams.h"
|
||||
@@ -48,7 +49,7 @@ BOOST_AUTO_TEST_CASE(pmt_test1)
|
||||
}
|
||||
|
||||
// calculate actual merkle root and height
|
||||
uint256 merkleRoot1 = block.ComputeMerkleRoot();
|
||||
uint256 merkleRoot1 = BlockMerkleRoot(block);
|
||||
std::vector<uint256> vTxid(nTx, uint256());
|
||||
for (unsigned int j=0; j<nTx; j++)
|
||||
vTxid[j] = block.vtx[j].GetHash();
|
||||
|
||||
@@ -84,11 +84,18 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
|
||||
block.clear();
|
||||
if (blocknum == 30) {
|
||||
// At this point we should need to combine 5 buckets to get enough data points
|
||||
// So estimateFee(1) should fail and estimateFee(2) should return somewhere around
|
||||
// 8*baserate
|
||||
// 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%
|
||||
BOOST_CHECK(mpool.estimateFee(1) == CFeeRate(0));
|
||||
BOOST_CHECK(mpool.estimateFee(2).GetFeePerK() < 8*baseRate.GetFeePerK() + deltaFee);
|
||||
BOOST_CHECK(mpool.estimateFee(2).GetFeePerK() > 8*baseRate.GetFeePerK() - deltaFee);
|
||||
BOOST_CHECK(mpool.estimateFee(2) == CFeeRate(0));
|
||||
BOOST_CHECK(mpool.estimateFee(3) == CFeeRate(0));
|
||||
BOOST_CHECK(mpool.estimateFee(4).GetFeePerK() < 8*baseRate.GetFeePerK() + deltaFee);
|
||||
BOOST_CHECK(mpool.estimateFee(4).GetFeePerK() > 8*baseRate.GetFeePerK() - deltaFee);
|
||||
int answerFound;
|
||||
BOOST_CHECK(mpool.estimateSmartFee(1, &answerFound) == mpool.estimateFee(4) && answerFound == 4);
|
||||
BOOST_CHECK(mpool.estimateSmartFee(3, &answerFound) == mpool.estimateFee(4) && answerFound == 4);
|
||||
BOOST_CHECK(mpool.estimateSmartFee(4, &answerFound) == mpool.estimateFee(4) && answerFound == 4);
|
||||
BOOST_CHECK(mpool.estimateSmartFee(8, &answerFound) == mpool.estimateFee(8) && answerFound == 8);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,9 +104,9 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
|
||||
// Highest feerate is 10*baseRate and gets in all blocks,
|
||||
// second highest feerate is 9*baseRate and gets in 9/10 blocks = 90%,
|
||||
// third highest feerate is 8*base rate, and gets in 8/10 blocks = 80%,
|
||||
// so estimateFee(1) should return 9*baseRate.
|
||||
// Third highest feerate has 90% chance of being included by 2 blocks,
|
||||
// so estimateFee(2) should return 8*baseRate etc...
|
||||
// so estimateFee(1) should return 10*baseRate.
|
||||
// Second highest feerate has 100% chance of being included by 2 blocks,
|
||||
// so estimateFee(2) should return 9*baseRate etc...
|
||||
for (int i = 1; i < 10;i++) {
|
||||
origFeeEst.push_back(mpool.estimateFee(i).GetFeePerK());
|
||||
origPriEst.push_back(mpool.estimatePriority(i));
|
||||
@@ -107,10 +114,11 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
|
||||
BOOST_CHECK(origFeeEst[i-1] <= origFeeEst[i-2]);
|
||||
BOOST_CHECK(origPriEst[i-1] <= origPriEst[i-2]);
|
||||
}
|
||||
BOOST_CHECK(origFeeEst[i-1] < (10-i)*baseRate.GetFeePerK() + deltaFee);
|
||||
BOOST_CHECK(origFeeEst[i-1] > (10-i)*baseRate.GetFeePerK() - deltaFee);
|
||||
BOOST_CHECK(origPriEst[i-1] < pow(10,10-i) * basepri + deltaPri);
|
||||
BOOST_CHECK(origPriEst[i-1] > pow(10,10-i) * basepri - deltaPri);
|
||||
int mult = 11-i;
|
||||
BOOST_CHECK(origFeeEst[i-1] < mult*baseRate.GetFeePerK() + deltaFee);
|
||||
BOOST_CHECK(origFeeEst[i-1] > mult*baseRate.GetFeePerK() - deltaFee);
|
||||
BOOST_CHECK(origPriEst[i-1] < pow(10,mult) * basepri + deltaPri);
|
||||
BOOST_CHECK(origPriEst[i-1] > pow(10,mult) * basepri - deltaPri);
|
||||
}
|
||||
|
||||
// Mine 50 more blocks with no transactions happening, estimates shouldn't change
|
||||
@@ -140,9 +148,12 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
|
||||
mpool.removeForBlock(block, ++blocknum, dummyConflicted);
|
||||
}
|
||||
|
||||
int answerFound;
|
||||
for (int i = 1; i < 10;i++) {
|
||||
BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() > origFeeEst[i-1] - deltaFee);
|
||||
BOOST_CHECK(mpool.estimatePriority(i) > origPriEst[i-1] - deltaPri);
|
||||
BOOST_CHECK(mpool.estimateFee(i) == CFeeRate(0) || mpool.estimateFee(i).GetFeePerK() > origFeeEst[i-1] - deltaFee);
|
||||
BOOST_CHECK(mpool.estimateSmartFee(i, &answerFound).GetFeePerK() > origFeeEst[answerFound-1] - deltaFee);
|
||||
BOOST_CHECK(mpool.estimatePriority(i) == -1 || mpool.estimatePriority(i) > origPriEst[i-1] - deltaPri);
|
||||
BOOST_CHECK(mpool.estimateSmartPriority(i, &answerFound) > origPriEst[answerFound-1] - deltaPri);
|
||||
}
|
||||
|
||||
// Mine all those transactions
|
||||
@@ -162,9 +173,9 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
|
||||
BOOST_CHECK(mpool.estimatePriority(i) > origPriEst[i-1] - deltaPri);
|
||||
}
|
||||
|
||||
// Mine 100 more blocks where everything is mined every block
|
||||
// Estimates should be below original estimates (not possible for last estimate)
|
||||
while (blocknum < 365) {
|
||||
// Mine 200 more blocks where everything is mined every block
|
||||
// Estimates should be below original estimates
|
||||
while (blocknum < 465) {
|
||||
for (int j = 0; j < 10; j++) { // For each fee/pri multiple
|
||||
for (int k = 0; k < 5; k++) { // add 4 fee txs for every priority tx
|
||||
tx.vin[0].prevout.n = 10000*blocknum+100*j+k;
|
||||
@@ -178,10 +189,22 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
|
||||
mpool.removeForBlock(block, ++blocknum, dummyConflicted);
|
||||
block.clear();
|
||||
}
|
||||
for (int i = 1; i < 9; i++) {
|
||||
for (int i = 1; i < 10; i++) {
|
||||
BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() < origFeeEst[i-1] - deltaFee);
|
||||
BOOST_CHECK(mpool.estimatePriority(i) < origPriEst[i-1] - deltaPri);
|
||||
}
|
||||
|
||||
// Test that if the mempool is limited, estimateSmartFee won't return a value below the mempool min fee
|
||||
// and that estimateSmartPriority returns essentially an infinite value
|
||||
mpool.addUnchecked(tx.GetHash(), entry.Fee(feeV[0][5]).Time(GetTime()).Priority(priV[1][5]).Height(blocknum).FromTx(tx, &mpool));
|
||||
// evict that transaction which should set a mempool min fee of minRelayTxFee + feeV[0][5]
|
||||
mpool.TrimToSize(1);
|
||||
BOOST_CHECK(mpool.GetMinFee(1).GetFeePerK() > feeV[0][5]);
|
||||
for (int i = 1; i < 10; i++) {
|
||||
BOOST_CHECK(mpool.estimateSmartFee(i).GetFeePerK() >= mpool.estimateFee(i).GetFeePerK());
|
||||
BOOST_CHECK(mpool.estimateSmartFee(i).GetFeePerK() >= mpool.GetMinFee(1).GetFeePerK());
|
||||
BOOST_CHECK(mpool.estimateSmartPriority(i) == INF_PRIORITY);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
217
src/test/prevector_tests.cpp
Normal file
217
src/test/prevector_tests.cpp
Normal file
@@ -0,0 +1,217 @@
|
||||
// Copyright (c) 2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <vector>
|
||||
#include "prevector.h"
|
||||
#include "random.h"
|
||||
|
||||
#include "serialize.h"
|
||||
#include "streams.h"
|
||||
|
||||
#include "test/test_bitcoin.h"
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(PrevectorTests, TestingSetup)
|
||||
|
||||
template<unsigned int N, typename T>
|
||||
class prevector_tester {
|
||||
typedef std::vector<T> realtype;
|
||||
realtype real_vector;
|
||||
|
||||
typedef prevector<N, T> pretype;
|
||||
pretype pre_vector;
|
||||
|
||||
typedef typename pretype::size_type Size;
|
||||
|
||||
void test() {
|
||||
const pretype& const_pre_vector = pre_vector;
|
||||
BOOST_CHECK_EQUAL(real_vector.size(), pre_vector.size());
|
||||
BOOST_CHECK_EQUAL(real_vector.empty(), pre_vector.empty());
|
||||
for (Size s = 0; s < real_vector.size(); s++) {
|
||||
BOOST_CHECK(real_vector[s] == pre_vector[s]);
|
||||
BOOST_CHECK(&(pre_vector[s]) == &(pre_vector.begin()[s]));
|
||||
BOOST_CHECK(&(pre_vector[s]) == &*(pre_vector.begin() + s));
|
||||
BOOST_CHECK(&(pre_vector[s]) == &*((pre_vector.end() + s) - real_vector.size()));
|
||||
}
|
||||
// BOOST_CHECK(realtype(pre_vector) == real_vector);
|
||||
BOOST_CHECK(pretype(real_vector.begin(), real_vector.end()) == pre_vector);
|
||||
BOOST_CHECK(pretype(pre_vector.begin(), pre_vector.end()) == pre_vector);
|
||||
size_t pos = 0;
|
||||
BOOST_FOREACH(const T& v, pre_vector) {
|
||||
BOOST_CHECK(v == real_vector[pos++]);
|
||||
}
|
||||
BOOST_REVERSE_FOREACH(const T& v, pre_vector) {
|
||||
BOOST_CHECK(v == real_vector[--pos]);
|
||||
}
|
||||
BOOST_FOREACH(const T& v, const_pre_vector) {
|
||||
BOOST_CHECK(v == real_vector[pos++]);
|
||||
}
|
||||
BOOST_REVERSE_FOREACH(const T& v, const_pre_vector) {
|
||||
BOOST_CHECK(v == real_vector[--pos]);
|
||||
}
|
||||
CDataStream ss1(SER_DISK, 0);
|
||||
CDataStream ss2(SER_DISK, 0);
|
||||
ss1 << real_vector;
|
||||
ss2 << pre_vector;
|
||||
BOOST_CHECK_EQUAL(ss1.size(), ss2.size());
|
||||
for (Size s = 0; s < ss1.size(); s++) {
|
||||
BOOST_CHECK_EQUAL(ss1[s], ss2[s]);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
void resize(Size s) {
|
||||
real_vector.resize(s);
|
||||
BOOST_CHECK_EQUAL(real_vector.size(), s);
|
||||
pre_vector.resize(s);
|
||||
BOOST_CHECK_EQUAL(pre_vector.size(), s);
|
||||
test();
|
||||
}
|
||||
|
||||
void reserve(Size s) {
|
||||
real_vector.reserve(s);
|
||||
BOOST_CHECK(real_vector.capacity() >= s);
|
||||
pre_vector.reserve(s);
|
||||
BOOST_CHECK(pre_vector.capacity() >= s);
|
||||
test();
|
||||
}
|
||||
|
||||
void insert(Size position, const T& value) {
|
||||
real_vector.insert(real_vector.begin() + position, value);
|
||||
pre_vector.insert(pre_vector.begin() + position, value);
|
||||
test();
|
||||
}
|
||||
|
||||
void insert(Size position, Size count, const T& value) {
|
||||
real_vector.insert(real_vector.begin() + position, count, value);
|
||||
pre_vector.insert(pre_vector.begin() + position, count, value);
|
||||
test();
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
void insert_range(Size position, I first, I last) {
|
||||
real_vector.insert(real_vector.begin() + position, first, last);
|
||||
pre_vector.insert(pre_vector.begin() + position, first, last);
|
||||
test();
|
||||
}
|
||||
|
||||
void erase(Size position) {
|
||||
real_vector.erase(real_vector.begin() + position);
|
||||
pre_vector.erase(pre_vector.begin() + position);
|
||||
test();
|
||||
}
|
||||
|
||||
void erase(Size first, Size last) {
|
||||
real_vector.erase(real_vector.begin() + first, real_vector.begin() + last);
|
||||
pre_vector.erase(pre_vector.begin() + first, pre_vector.begin() + last);
|
||||
test();
|
||||
}
|
||||
|
||||
void update(Size pos, const T& value) {
|
||||
real_vector[pos] = value;
|
||||
pre_vector[pos] = value;
|
||||
test();
|
||||
}
|
||||
|
||||
void push_back(const T& value) {
|
||||
real_vector.push_back(value);
|
||||
pre_vector.push_back(value);
|
||||
test();
|
||||
}
|
||||
|
||||
void pop_back() {
|
||||
real_vector.pop_back();
|
||||
pre_vector.pop_back();
|
||||
test();
|
||||
}
|
||||
|
||||
void clear() {
|
||||
real_vector.clear();
|
||||
pre_vector.clear();
|
||||
}
|
||||
|
||||
void assign(Size n, const T& value) {
|
||||
real_vector.assign(n, value);
|
||||
pre_vector.assign(n, value);
|
||||
}
|
||||
|
||||
Size size() {
|
||||
return real_vector.size();
|
||||
}
|
||||
|
||||
Size capacity() {
|
||||
return pre_vector.capacity();
|
||||
}
|
||||
|
||||
void shrink_to_fit() {
|
||||
pre_vector.shrink_to_fit();
|
||||
test();
|
||||
}
|
||||
};
|
||||
|
||||
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 (test.size() > 0 && ((r >> 2) % 4) == 1) {
|
||||
test.erase(insecure_rand() % test.size());
|
||||
}
|
||||
if (((r >> 4) % 8) == 2) {
|
||||
int new_size = std::max<int>(0, std::min<int>(30, test.size() + (insecure_rand() % 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 (((r >> 10) % 8) == 4) {
|
||||
int del = std::min<int>(test.size(), 1 + (insecure_rand() % 2));
|
||||
int beg = insecure_rand() % (test.size() + 1 - del);
|
||||
test.erase(beg, beg + del);
|
||||
}
|
||||
if (((r >> 13) % 16) == 5) {
|
||||
test.push_back(insecure_rand());
|
||||
}
|
||||
if (test.size() > 0 && ((r >> 17) % 16) == 6) {
|
||||
test.pop_back();
|
||||
}
|
||||
if (((r >> 21) % 32) == 7) {
|
||||
int values[4];
|
||||
int num = 1 + (insecure_rand() % 4);
|
||||
for (int i = 0; i < num; i++) {
|
||||
values[i] = insecure_rand();
|
||||
}
|
||||
test.insert_range(insecure_rand() % (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);
|
||||
test.erase(beg, beg + del);
|
||||
}
|
||||
r = insecure_rand();
|
||||
if (r % 32 == 9) {
|
||||
test.reserve(insecure_rand() % 32);
|
||||
}
|
||||
if ((r >> 5) % 64 == 10) {
|
||||
test.shrink_to_fit();
|
||||
}
|
||||
if (test.size() > 0) {
|
||||
test.update(insecure_rand() % test.size(), insecure_rand());
|
||||
}
|
||||
if (((r >> 11) & 1024) == 11) {
|
||||
test.clear();
|
||||
}
|
||||
if (((r >> 21) & 512) == 12) {
|
||||
test.assign(insecure_rand() % 32, insecure_rand());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
@@ -42,22 +42,18 @@ BOOST_AUTO_TEST_CASE(reverselock_errors)
|
||||
BOOST_CHECK(failed);
|
||||
BOOST_CHECK(!lock.owns_lock());
|
||||
|
||||
// Make sure trying to lock a lock after it has been reverse locked fails
|
||||
failed = false;
|
||||
bool locked = false;
|
||||
// Locking the original lock after it has been taken by a reverse lock
|
||||
// makes no sense. Ensure that the original lock no longer owns the lock
|
||||
// after giving it to a reverse one.
|
||||
|
||||
lock.lock();
|
||||
BOOST_CHECK(lock.owns_lock());
|
||||
|
||||
try {
|
||||
{
|
||||
reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock);
|
||||
lock.lock();
|
||||
locked = true;
|
||||
} catch(...) {
|
||||
failed = true;
|
||||
BOOST_CHECK(!lock.owns_lock());
|
||||
}
|
||||
|
||||
BOOST_CHECK(locked && failed);
|
||||
BOOST_CHECK(failed);
|
||||
BOOST_CHECK(lock.owns_lock());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// Copyright (c) 2012-2013 The Bitcoin Core developers
|
||||
// Copyright (c) 2012-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "rpcserver.h"
|
||||
#include "rpcclient.h"
|
||||
#include "rpc/server.h"
|
||||
#include "rpc/client.h"
|
||||
|
||||
#include "base58.h"
|
||||
#include "netbase.h"
|
||||
@@ -72,6 +72,7 @@ BOOST_AUTO_TEST_CASE(rpc_rawparams)
|
||||
BOOST_CHECK_THROW(CallRPC("decoderawtransaction DEADBEEF"), runtime_error);
|
||||
string rawtx = "0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000";
|
||||
BOOST_CHECK_NO_THROW(r = CallRPC(string("decoderawtransaction ")+rawtx));
|
||||
BOOST_CHECK_EQUAL(find_value(r.get_obj(), "size").get_int(), 193);
|
||||
BOOST_CHECK_EQUAL(find_value(r.get_obj(), "version").get_int(), 1);
|
||||
BOOST_CHECK_EQUAL(find_value(r.get_obj(), "locktime").get_int(), 0);
|
||||
BOOST_CHECK_THROW(r = CallRPC(string("decoderawtransaction ")+rawtx+" extra"), runtime_error);
|
||||
@@ -236,7 +237,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban)
|
||||
UniValue o1 = ar[0].get_obj();
|
||||
UniValue adr = find_value(o1, "address");
|
||||
BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/32");
|
||||
BOOST_CHECK_NO_THROW(CallRPC(string("setban 127.0.0.0 remove")));;
|
||||
BOOST_CHECK_NO_THROW(CallRPC(string("setban 127.0.0.0 remove")));
|
||||
BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned")));
|
||||
ar = r.get_array();
|
||||
BOOST_CHECK_EQUAL(ar.size(), 0);
|
||||
@@ -259,14 +260,14 @@ BOOST_AUTO_TEST_CASE(rpc_ban)
|
||||
adr = find_value(o1, "address");
|
||||
banned_until = find_value(o1, "banned_until");
|
||||
BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/24");
|
||||
int64_t now = GetTime();
|
||||
int64_t now = GetTime();
|
||||
BOOST_CHECK(banned_until.get_int64() > now);
|
||||
BOOST_CHECK(banned_until.get_int64()-now <= 200);
|
||||
|
||||
// must throw an exception because 127.0.0.1 is in already banned suubnet range
|
||||
BOOST_CHECK_THROW(r = CallRPC(string("setban 127.0.0.1 add")), runtime_error);
|
||||
|
||||
BOOST_CHECK_NO_THROW(CallRPC(string("setban 127.0.0.0/24 remove")));;
|
||||
BOOST_CHECK_NO_THROW(CallRPC(string("setban 127.0.0.0/24 remove")));
|
||||
BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned")));
|
||||
ar = r.get_array();
|
||||
BOOST_CHECK_EQUAL(ar.size(), 0);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// Copyright (c) 2013-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2013-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "rpcserver.h"
|
||||
#include "rpcclient.h"
|
||||
#include "rpc/server.h"
|
||||
#include "rpc/client.h"
|
||||
|
||||
#include "base58.h"
|
||||
#include "main.h"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2013 The Bitcoin Core developers
|
||||
// Copyright (c) 2012-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2013 The Bitcoin Core developers
|
||||
// Copyright (c) 2012-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -40,6 +40,7 @@ static void MicroSleep(uint64_t n)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0 /* Disabled for now because there is a race condition issue in this test - see #6540 */
|
||||
BOOST_AUTO_TEST_CASE(manythreads)
|
||||
{
|
||||
seed_insecure_rand(false);
|
||||
@@ -115,5 +116,6 @@ BOOST_AUTO_TEST_CASE(manythreads)
|
||||
}
|
||||
BOOST_CHECK_EQUAL(counterSum, 200);
|
||||
}
|
||||
#endif
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2013 The Bitcoin Core developers
|
||||
// Copyright (c) 2012-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -25,7 +25,7 @@ using namespace std;
|
||||
static std::vector<unsigned char>
|
||||
Serialize(const CScript& s)
|
||||
{
|
||||
std::vector<unsigned char> sSerialized(s);
|
||||
std::vector<unsigned char> sSerialized(s.begin(), s.end());
|
||||
return sSerialized;
|
||||
}
|
||||
|
||||
@@ -339,22 +339,13 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
|
||||
// SignSignature doesn't know how to sign these. We're
|
||||
// not testing validating signatures, so just create
|
||||
// dummy signatures that DO include the correct P2SH scripts:
|
||||
txTo.vin[3].scriptSig << OP_11 << OP_11 << static_cast<vector<unsigned char> >(oneAndTwo);
|
||||
txTo.vin[4].scriptSig << static_cast<vector<unsigned char> >(fifteenSigops);
|
||||
txTo.vin[3].scriptSig << OP_11 << OP_11 << vector<unsigned char>(oneAndTwo.begin(), oneAndTwo.end());
|
||||
txTo.vin[4].scriptSig << vector<unsigned char>(fifteenSigops.begin(), fifteenSigops.end());
|
||||
|
||||
BOOST_CHECK(::AreInputsStandard(txTo, coins));
|
||||
// 22 P2SH sigops for all inputs (1 for vin[0], 6 for vin[3], 15 for vin[4]
|
||||
BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txTo, coins), 22U);
|
||||
|
||||
// Make sure adding crap to the scriptSigs makes them non-standard:
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
CScript t = txTo.vin[i].scriptSig;
|
||||
txTo.vin[i].scriptSig = (CScript() << 11) + t;
|
||||
BOOST_CHECK(!::AreInputsStandard(txTo, coins));
|
||||
txTo.vin[i].scriptSig = t;
|
||||
}
|
||||
|
||||
CMutableTransaction txToNonStd1;
|
||||
txToNonStd1.vout.resize(1);
|
||||
txToNonStd1.vout[0].scriptPubKey = GetScriptForDestination(key[1].GetPubKey().GetID());
|
||||
@@ -362,7 +353,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
|
||||
txToNonStd1.vin.resize(1);
|
||||
txToNonStd1.vin[0].prevout.n = 5;
|
||||
txToNonStd1.vin[0].prevout.hash = txFrom.GetHash();
|
||||
txToNonStd1.vin[0].scriptSig << static_cast<vector<unsigned char> >(sixteenSigops);
|
||||
txToNonStd1.vin[0].scriptSig << vector<unsigned char>(sixteenSigops.begin(), sixteenSigops.end());
|
||||
|
||||
BOOST_CHECK(!::AreInputsStandard(txToNonStd1, coins));
|
||||
BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txToNonStd1, coins), 16U);
|
||||
@@ -374,7 +365,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
|
||||
txToNonStd2.vin.resize(1);
|
||||
txToNonStd2.vin[0].prevout.n = 6;
|
||||
txToNonStd2.vin[0].prevout.hash = txFrom.GetHash();
|
||||
txToNonStd2.vin[0].scriptSig << static_cast<vector<unsigned char> >(twentySigops);
|
||||
txToNonStd2.vin[0].scriptSig << vector<unsigned char>(twentySigops.begin(), twentySigops.end());
|
||||
|
||||
BOOST_CHECK(!::AreInputsStandard(txToNonStd2, coins));
|
||||
BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txToNonStd2, coins), 20U);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2011-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2011-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -260,7 +260,7 @@ public:
|
||||
|
||||
TestBuilder& PushRedeem()
|
||||
{
|
||||
DoPush(static_cast<std::vector<unsigned char> >(scriptPubKey));
|
||||
DoPush(std::vector<unsigned char>(scriptPubKey.begin(), scriptPubKey.end()));
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -892,7 +892,7 @@ BOOST_AUTO_TEST_CASE(script_combineSigs)
|
||||
combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSigCopy, scriptSig);
|
||||
BOOST_CHECK(combined == scriptSigCopy || combined == scriptSig);
|
||||
// dummy scriptSigCopy with placeholder, should always choose non-placeholder:
|
||||
scriptSigCopy = CScript() << OP_0 << static_cast<vector<unsigned char> >(pkSingle);
|
||||
scriptSigCopy = CScript() << OP_0 << vector<unsigned char>(pkSingle.begin(), pkSingle.end());
|
||||
combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSigCopy, scriptSig);
|
||||
BOOST_CHECK(combined == scriptSig);
|
||||
combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, scriptSigCopy);
|
||||
@@ -985,10 +985,10 @@ BOOST_AUTO_TEST_CASE(script_IsPushOnly_on_invalid_scripts)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(script_GetScriptAsm)
|
||||
{
|
||||
BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_NOP2, true));
|
||||
BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY, true));
|
||||
BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_NOP2));
|
||||
BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY));
|
||||
BOOST_CHECK_EQUAL("OP_CHECKLOCKTIMEVERIFY", ScriptToAsmStr(CScript() << OP_NOP2, true));
|
||||
BOOST_CHECK_EQUAL("OP_CHECKLOCKTIMEVERIFY", ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY, true));
|
||||
BOOST_CHECK_EQUAL("OP_CHECKLOCKTIMEVERIFY", ScriptToAsmStr(CScript() << OP_NOP2));
|
||||
BOOST_CHECK_EQUAL("OP_CHECKLOCKTIMEVERIFY", ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY));
|
||||
|
||||
string derSig("304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c5090");
|
||||
string pubKey("03b0da749730dc9b4b1f4a14d6902877a92541f5368778853d9c4a0cb7802dcfb2");
|
||||
|
||||
183
src/test/scriptnum10.h
Normal file
183
src/test/scriptnum10.h
Normal file
@@ -0,0 +1,183 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2015 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_SCRIPTNUM10_H
|
||||
#define BITCOIN_TEST_SCRIPTNUM10_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "assert.h"
|
||||
|
||||
class scriptnum10_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
explicit scriptnum10_error(const std::string& str) : std::runtime_error(str) {}
|
||||
};
|
||||
|
||||
class CScriptNum10
|
||||
{
|
||||
/**
|
||||
* The ScriptNum implementation from Bitcoin Core 0.10.0, for cross-comparison.
|
||||
*/
|
||||
public:
|
||||
|
||||
explicit CScriptNum10(const int64_t& n)
|
||||
{
|
||||
m_value = n;
|
||||
}
|
||||
|
||||
static const size_t nDefaultMaxNumSize = 4;
|
||||
|
||||
explicit CScriptNum10(const std::vector<unsigned char>& vch, bool fRequireMinimal,
|
||||
const size_t nMaxNumSize = nDefaultMaxNumSize)
|
||||
{
|
||||
if (vch.size() > nMaxNumSize) {
|
||||
throw scriptnum10_error("script number overflow");
|
||||
}
|
||||
if (fRequireMinimal && vch.size() > 0) {
|
||||
// Check that the number is encoded with the minimum possible
|
||||
// number of bytes.
|
||||
//
|
||||
// If the most-significant-byte - excluding the sign bit - is zero
|
||||
// then we're not minimal. Note how this test also rejects the
|
||||
// negative-zero encoding, 0x80.
|
||||
if ((vch.back() & 0x7f) == 0) {
|
||||
// One exception: if there's more than one byte and the most
|
||||
// significant bit of the second-most-significant-byte is set
|
||||
// it would conflict with the sign bit. An example of this case
|
||||
// is +-255, which encode to 0xff00 and 0xff80 respectively.
|
||||
// (big-endian).
|
||||
if (vch.size() <= 1 || (vch[vch.size() - 2] & 0x80) == 0) {
|
||||
throw scriptnum10_error("non-minimally encoded script number");
|
||||
}
|
||||
}
|
||||
}
|
||||
m_value = set_vch(vch);
|
||||
}
|
||||
|
||||
inline bool operator==(const int64_t& rhs) const { return m_value == rhs; }
|
||||
inline bool operator!=(const int64_t& rhs) const { return m_value != rhs; }
|
||||
inline bool operator<=(const int64_t& rhs) const { return m_value <= rhs; }
|
||||
inline bool operator< (const int64_t& rhs) const { return m_value < rhs; }
|
||||
inline bool operator>=(const int64_t& rhs) const { return m_value >= rhs; }
|
||||
inline bool operator> (const int64_t& rhs) const { return m_value > rhs; }
|
||||
|
||||
inline bool operator==(const CScriptNum10& rhs) const { return operator==(rhs.m_value); }
|
||||
inline bool operator!=(const CScriptNum10& rhs) const { return operator!=(rhs.m_value); }
|
||||
inline bool operator<=(const CScriptNum10& rhs) const { return operator<=(rhs.m_value); }
|
||||
inline bool operator< (const CScriptNum10& rhs) const { return operator< (rhs.m_value); }
|
||||
inline bool operator>=(const CScriptNum10& rhs) const { return operator>=(rhs.m_value); }
|
||||
inline bool operator> (const CScriptNum10& rhs) const { return operator> (rhs.m_value); }
|
||||
|
||||
inline CScriptNum10 operator+( const int64_t& rhs) const { return CScriptNum10(m_value + rhs);}
|
||||
inline CScriptNum10 operator-( const int64_t& rhs) const { return CScriptNum10(m_value - rhs);}
|
||||
inline CScriptNum10 operator+( const CScriptNum10& rhs) const { return operator+(rhs.m_value); }
|
||||
inline CScriptNum10 operator-( const CScriptNum10& rhs) const { return operator-(rhs.m_value); }
|
||||
|
||||
inline CScriptNum10& operator+=( const CScriptNum10& rhs) { return operator+=(rhs.m_value); }
|
||||
inline CScriptNum10& operator-=( const CScriptNum10& rhs) { return operator-=(rhs.m_value); }
|
||||
|
||||
inline CScriptNum10 operator-() const
|
||||
{
|
||||
assert(m_value != std::numeric_limits<int64_t>::min());
|
||||
return CScriptNum10(-m_value);
|
||||
}
|
||||
|
||||
inline CScriptNum10& operator=( const int64_t& rhs)
|
||||
{
|
||||
m_value = rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CScriptNum10& operator+=( const int64_t& rhs)
|
||||
{
|
||||
assert(rhs == 0 || (rhs > 0 && m_value <= std::numeric_limits<int64_t>::max() - rhs) ||
|
||||
(rhs < 0 && m_value >= std::numeric_limits<int64_t>::min() - rhs));
|
||||
m_value += rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CScriptNum10& operator-=( const int64_t& rhs)
|
||||
{
|
||||
assert(rhs == 0 || (rhs > 0 && m_value >= std::numeric_limits<int64_t>::min() + rhs) ||
|
||||
(rhs < 0 && m_value <= std::numeric_limits<int64_t>::max() + rhs));
|
||||
m_value -= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
int getint() const
|
||||
{
|
||||
if (m_value > std::numeric_limits<int>::max())
|
||||
return std::numeric_limits<int>::max();
|
||||
else if (m_value < std::numeric_limits<int>::min())
|
||||
return std::numeric_limits<int>::min();
|
||||
return m_value;
|
||||
}
|
||||
|
||||
std::vector<unsigned char> getvch() const
|
||||
{
|
||||
return serialize(m_value);
|
||||
}
|
||||
|
||||
static std::vector<unsigned char> serialize(const int64_t& value)
|
||||
{
|
||||
if(value == 0)
|
||||
return std::vector<unsigned char>();
|
||||
|
||||
std::vector<unsigned char> result;
|
||||
const bool neg = value < 0;
|
||||
uint64_t absvalue = neg ? -value : value;
|
||||
|
||||
while(absvalue)
|
||||
{
|
||||
result.push_back(absvalue & 0xff);
|
||||
absvalue >>= 8;
|
||||
}
|
||||
|
||||
// - If the most significant byte is >= 0x80 and the value is positive, push a
|
||||
// new zero-byte to make the significant byte < 0x80 again.
|
||||
|
||||
// - If the most significant byte is >= 0x80 and the value is negative, push a
|
||||
// new 0x80 byte that will be popped off when converting to an integral.
|
||||
|
||||
// - If the most significant byte is < 0x80 and the value is negative, add
|
||||
// 0x80 to it, since it will be subtracted and interpreted as a negative when
|
||||
// converting to an integral.
|
||||
|
||||
if (result.back() & 0x80)
|
||||
result.push_back(neg ? 0x80 : 0);
|
||||
else if (neg)
|
||||
result.back() |= 0x80;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
static int64_t set_vch(const std::vector<unsigned char>& vch)
|
||||
{
|
||||
if (vch.empty())
|
||||
return 0;
|
||||
|
||||
int64_t result = 0;
|
||||
for (size_t i = 0; i != vch.size(); ++i)
|
||||
result |= static_cast<int64_t>(vch[i]) << 8*i;
|
||||
|
||||
// If the input vector's most significant byte is 0x80, remove it from
|
||||
// the result's msb and return a negative.
|
||||
if (vch.back() & 0x80)
|
||||
return -((int64_t)(result & ~(0x80ULL << (8 * (vch.size() - 1)))));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int64_t m_value;
|
||||
};
|
||||
|
||||
|
||||
#endif // BITCOIN_TEST_BIGNUM_H
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) 2012-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2012-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "bignum.h"
|
||||
#include "scriptnum10.h"
|
||||
#include "script/script.h"
|
||||
#include "test/test_bitcoin.h"
|
||||
|
||||
@@ -16,45 +16,48 @@ static const int64_t values[] = \
|
||||
{ 0, 1, CHAR_MIN, CHAR_MAX, UCHAR_MAX, SHRT_MIN, USHRT_MAX, INT_MIN, INT_MAX, UINT_MAX, LONG_MIN, LONG_MAX };
|
||||
static const int64_t offsets[] = { 1, 0x79, 0x80, 0x81, 0xFF, 0x7FFF, 0x8000, 0xFFFF, 0x10000};
|
||||
|
||||
static bool verify(const CBigNum& bignum, const CScriptNum& scriptnum)
|
||||
static bool verify(const CScriptNum10& bignum, const CScriptNum& scriptnum)
|
||||
{
|
||||
return bignum.getvch() == scriptnum.getvch() && bignum.getint() == scriptnum.getint();
|
||||
}
|
||||
|
||||
static void CheckCreateVch(const int64_t& num)
|
||||
{
|
||||
CBigNum bignum(num);
|
||||
CScriptNum10 bignum(num);
|
||||
CScriptNum scriptnum(num);
|
||||
BOOST_CHECK(verify(bignum, scriptnum));
|
||||
|
||||
CBigNum bignum2(bignum.getvch());
|
||||
std::vector<unsigned char> vch = bignum.getvch();
|
||||
|
||||
CScriptNum10 bignum2(bignum.getvch(), false);
|
||||
vch = scriptnum.getvch();
|
||||
CScriptNum scriptnum2(scriptnum.getvch(), false);
|
||||
BOOST_CHECK(verify(bignum2, scriptnum2));
|
||||
|
||||
CBigNum bignum3(scriptnum2.getvch());
|
||||
CScriptNum10 bignum3(scriptnum2.getvch(), false);
|
||||
CScriptNum scriptnum3(bignum2.getvch(), false);
|
||||
BOOST_CHECK(verify(bignum3, scriptnum3));
|
||||
}
|
||||
|
||||
static void CheckCreateInt(const int64_t& num)
|
||||
{
|
||||
CBigNum bignum(num);
|
||||
CScriptNum10 bignum(num);
|
||||
CScriptNum scriptnum(num);
|
||||
BOOST_CHECK(verify(bignum, scriptnum));
|
||||
BOOST_CHECK(verify(bignum.getint(), CScriptNum(scriptnum.getint())));
|
||||
BOOST_CHECK(verify(scriptnum.getint(), CScriptNum(bignum.getint())));
|
||||
BOOST_CHECK(verify(CBigNum(scriptnum.getint()).getint(), CScriptNum(CScriptNum(bignum.getint()).getint())));
|
||||
BOOST_CHECK(verify(CScriptNum10(bignum.getint()), CScriptNum(scriptnum.getint())));
|
||||
BOOST_CHECK(verify(CScriptNum10(scriptnum.getint()), CScriptNum(bignum.getint())));
|
||||
BOOST_CHECK(verify(CScriptNum10(CScriptNum10(scriptnum.getint()).getint()), CScriptNum(CScriptNum(bignum.getint()).getint())));
|
||||
}
|
||||
|
||||
|
||||
static void CheckAdd(const int64_t& num1, const int64_t& num2)
|
||||
{
|
||||
const CBigNum bignum1(num1);
|
||||
const CBigNum bignum2(num2);
|
||||
const CScriptNum10 bignum1(num1);
|
||||
const CScriptNum10 bignum2(num2);
|
||||
const CScriptNum scriptnum1(num1);
|
||||
const CScriptNum scriptnum2(num2);
|
||||
CBigNum bignum3(num1);
|
||||
CBigNum bignum4(num1);
|
||||
CScriptNum10 bignum3(num1);
|
||||
CScriptNum10 bignum4(num1);
|
||||
CScriptNum scriptnum3(num1);
|
||||
CScriptNum scriptnum4(num1);
|
||||
|
||||
@@ -71,7 +74,7 @@ static void CheckAdd(const int64_t& num1, const int64_t& num2)
|
||||
|
||||
static void CheckNegate(const int64_t& num)
|
||||
{
|
||||
const CBigNum bignum(num);
|
||||
const CScriptNum10 bignum(num);
|
||||
const CScriptNum scriptnum(num);
|
||||
|
||||
// -INT64_MIN is undefined
|
||||
@@ -81,8 +84,8 @@ static void CheckNegate(const int64_t& num)
|
||||
|
||||
static void CheckSubtract(const int64_t& num1, const int64_t& num2)
|
||||
{
|
||||
const CBigNum bignum1(num1);
|
||||
const CBigNum bignum2(num2);
|
||||
const CScriptNum10 bignum1(num1);
|
||||
const CScriptNum10 bignum2(num2);
|
||||
const CScriptNum scriptnum1(num1);
|
||||
const CScriptNum scriptnum2(num2);
|
||||
bool invalid = false;
|
||||
@@ -107,8 +110,8 @@ static void CheckSubtract(const int64_t& num1, const int64_t& num2)
|
||||
|
||||
static void CheckCompare(const int64_t& num1, const int64_t& num2)
|
||||
{
|
||||
const CBigNum bignum1(num1);
|
||||
const CBigNum bignum2(num2);
|
||||
const CScriptNum10 bignum1(num1);
|
||||
const CScriptNum10 bignum2(num2);
|
||||
const CScriptNum scriptnum1(num1);
|
||||
const CScriptNum scriptnum2(num2);
|
||||
|
||||
@@ -149,7 +152,7 @@ static void RunCreate(const int64_t& num)
|
||||
CheckCreateVch(num);
|
||||
else
|
||||
{
|
||||
BOOST_CHECK_THROW (CheckCreateVch(num), scriptnum_error);
|
||||
BOOST_CHECK_THROW (CheckCreateVch(num), scriptnum10_error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2013 The Bitcoin Core developers
|
||||
// Copyright (c) 2012-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2013 The Bitcoin Core developers
|
||||
// Copyright (c) 2013-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2013 The Bitcoin Core developers
|
||||
// Copyright (c) 2012-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -20,7 +20,7 @@ using namespace std;
|
||||
static std::vector<unsigned char>
|
||||
Serialize(const CScript& s)
|
||||
{
|
||||
std::vector<unsigned char> sSerialized(s);
|
||||
std::vector<unsigned char> sSerialized(s.begin(), s.end());
|
||||
return sSerialized;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2014-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2013 The Bitcoin Core developers
|
||||
// Copyright (c) 2012-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2011-2013 The Bitcoin Core developers
|
||||
// Copyright (c) 2011-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -51,8 +51,10 @@ BasicTestingSetup::~BasicTestingSetup()
|
||||
|
||||
TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(chainName)
|
||||
{
|
||||
const CChainParams& chainparams = Params();
|
||||
#ifdef ENABLE_WALLET
|
||||
bitdb.MakeMock();
|
||||
walletRegisterRPCCommands();
|
||||
#endif
|
||||
ClearDatadirCache();
|
||||
pathTemp = GetTempPath() / strprintf("test_bitcoin_%lu_%i", (unsigned long)GetTime(), (int)(GetRand(100000)));
|
||||
@@ -61,7 +63,7 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha
|
||||
pblocktree = new CBlockTreeDB(1 << 20, true);
|
||||
pcoinsdbview = new CCoinsViewDB(1 << 23, true);
|
||||
pcoinsTip = new CCoinsViewCache(pcoinsdbview);
|
||||
InitBlockIndex();
|
||||
InitBlockIndex(chainparams);
|
||||
#ifdef ENABLE_WALLET
|
||||
bool fFirstRun;
|
||||
pwalletMain = new CWallet("wallet.dat");
|
||||
@@ -143,8 +145,13 @@ TestChain100Setup::~TestChain100Setup()
|
||||
|
||||
|
||||
CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(CMutableTransaction &tx, CTxMemPool *pool) {
|
||||
return CTxMemPoolEntry(tx, nFee, nTime, dPriority, nHeight,
|
||||
pool ? pool->HasNoInputsOf(tx) : hadNoDependencies);
|
||||
CTransaction txn(tx);
|
||||
bool hasNoDependencies = pool ? pool->HasNoInputsOf(tx) : hadNoDependencies;
|
||||
// Hack to assume either its completely dependent on other mempool txs or not at all
|
||||
CAmount inChainValue = hasNoDependencies ? txn.GetValueOut() : 0;
|
||||
|
||||
return CTxMemPoolEntry(txn, nFee, nTime, dPriority, nHeight,
|
||||
hasNoDependencies, inChainValue, spendsCoinbase, sigOpCount);
|
||||
}
|
||||
|
||||
void Shutdown(void* parg)
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
// Copyright (c) 2015 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_TEST_BITCOIN_H
|
||||
#define BITCOIN_TEST_TEST_BITCOIN_H
|
||||
|
||||
@@ -65,11 +69,13 @@ struct TestMemPoolEntryHelper
|
||||
double dPriority;
|
||||
unsigned int nHeight;
|
||||
bool hadNoDependencies;
|
||||
|
||||
bool spendsCoinbase;
|
||||
unsigned int sigOpCount;
|
||||
|
||||
TestMemPoolEntryHelper() :
|
||||
nFee(0), nTime(0), dPriority(0.0), nHeight(1),
|
||||
hadNoDependencies(false) { }
|
||||
|
||||
hadNoDependencies(false), spendsCoinbase(false), sigOpCount(1) { }
|
||||
|
||||
CTxMemPoolEntry FromTx(CMutableTransaction &tx, CTxMemPool *pool = NULL);
|
||||
|
||||
// Change the default value
|
||||
@@ -78,5 +84,7 @@ struct TestMemPoolEntryHelper
|
||||
TestMemPoolEntryHelper &Priority(double _priority) { dPriority = _priority; return *this; }
|
||||
TestMemPoolEntryHelper &Height(unsigned int _height) { nHeight = _height; return *this; }
|
||||
TestMemPoolEntryHelper &HadNoDependencies(bool _hnd) { hadNoDependencies = _hnd; return *this; }
|
||||
TestMemPoolEntryHelper &SpendsCoinbase(bool _flag) { spendsCoinbase = _flag; return *this; }
|
||||
TestMemPoolEntryHelper &SigOps(unsigned int _sigops) { sigOpCount = _sigops; return *this; }
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2011-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2011-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
//
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2011-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2011-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -310,14 +310,6 @@ BOOST_AUTO_TEST_CASE(test_Get)
|
||||
|
||||
BOOST_CHECK(AreInputsStandard(t1, coins));
|
||||
BOOST_CHECK_EQUAL(coins.GetValueIn(t1), (50+21+22)*CENT);
|
||||
|
||||
// Adding extra junk to the scriptSig should make it non-standard:
|
||||
t1.vin[0].scriptSig << OP_11;
|
||||
BOOST_CHECK(!AreInputsStandard(t1, coins));
|
||||
|
||||
// ... as should not having enough:
|
||||
t1.vin[0].scriptSig = CScript();
|
||||
BOOST_CHECK(!AreInputsStandard(t1, coins));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_IsStandard)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2011-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2011-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2011-2013 The Bitcoin Core developers
|
||||
// Copyright (c) 2011-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#include "arith_uint256.h"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// Copyright 2014 BitPay, Inc.
|
||||
// Copyright (c) 2014-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2011-2014 The Bitcoin Core developers
|
||||
// Copyright (c) 2011-2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user