Changeset View
Changeset View
Standalone View
Standalone View
src/seeder/test/seeder_tests.cpp
// Copyright (c) 2019 The Bitcoin developers | // Copyright (c) 2019 The Bitcoin developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#define BOOST_TEST_MODULE Bitcoin Seeder Test Suite | #define BOOST_TEST_MODULE Bitcoin Seeder Test Suite | ||||
#include <chainparams.h> | |||||
#include <protocol.h> | |||||
#include <seeder/bitcoin.h> | |||||
#include <seeder/db.h> | |||||
#include <serialize.h> | |||||
#include <streams.h> | |||||
#include <util/system.h> | |||||
#include <version.h> | |||||
#include <memory> | |||||
#include <string> | |||||
#include <vector> | |||||
const std::function<std::string(const char *)> G_TRANSLATION_FUN = nullptr; | |||||
#include <boost/test/unit_test.hpp> | #include <boost/test/unit_test.hpp> | ||||
BOOST_AUTO_TEST_SUITE(seeder_tests) | static const unsigned short SERVICE_PORT = 18444; | ||||
static const uint32_t VERACK_PAYLOAD = 0; | |||||
// After the 1000th addr, the seeder will only add one more address from an addr | |||||
// message. | |||||
static const int ADDR_SOFT_CAP = 1000; | |||||
static CDataStream | |||||
CreateVersionMessage(int64_t now, CAddress addrTo, CAddress addrFrom, | |||||
int32_t start_height, uint64_t nonce = 0, | |||||
std::string user_agent = "/bitcoin-cash-seeder:0.15/", | |||||
uint32_t nVersion = INIT_PROTO_VERSION) { | |||||
CDataStream payload(SER_NETWORK, 0); | |||||
payload.SetVersion(nVersion); | |||||
ServiceFlags service = ServiceFlags(NODE_NETWORK); | |||||
payload << nVersion << uint64_t(service) << now << addrTo << addrFrom | |||||
<< nonce << user_agent << start_height; | |||||
return payload; | |||||
} | |||||
// Verack message consists of only the header with NetMsgType::VERACK as the | |||||
// command string. | |||||
static CDataStream CreateVerackMessage(uint32_t nVersion = INIT_PROTO_VERSION) { | |||||
CDataStream payload(SER_NETWORK, 0); | |||||
payload.SetVersion(nVersion); | |||||
payload << VERACK_PAYLOAD; | |||||
return payload; | |||||
} | |||||
static CDataStream CreateAddrMessage(std::vector<CAddress> sendAddrs, | |||||
uint32_t nVersion = INIT_PROTO_VERSION) { | |||||
CDataStream payload(SER_NETWORK, 0); | |||||
payload.SetVersion(nVersion); | |||||
payload << sendAddrs; | |||||
return payload; | |||||
} | |||||
class TestCSeederNode : public CSeederNode { | |||||
public: | |||||
TestCSeederNode(const CService &service, std::vector<CAddress> *vAddrIn) | |||||
: CSeederNode(service, vAddrIn) { | |||||
SelectParams(CBaseChainParams::REGTEST); | |||||
} | |||||
void TestProcessMessage(const std::string &strCommand, | |||||
std::vector<CAddress> &addrs) { | |||||
if (strCommand == NetMsgType::VERSION) { | |||||
CService serviceFrom; | |||||
CAddress addrFrom(serviceFrom, | |||||
ServiceFlags(NODE_NETWORK | NODE_BITCOIN_CASH)); | |||||
CDataStream versionMessage = CreateVersionMessage( | |||||
time(nullptr), addrs[0], addrFrom, GetRequireHeight()); | |||||
bool ret = CSeederNode::ProcessMessage(strCommand, versionMessage); | |||||
BOOST_CHECK_EQUAL(ret, false); | |||||
int version = versionMessage.GetVersion() < PROTOCOL_VERSION | |||||
? versionMessage.GetVersion() | |||||
: PROTOCOL_VERSION; | |||||
BOOST_CHECK_EQUAL(CSeederNode::GetClientVersion(), version); | |||||
return; | |||||
} | |||||
if (strCommand == NetMsgType::VERACK) { | |||||
CDataStream verackMessage = CreateVerackMessage(); | |||||
bool ret = | |||||
CSeederNode::ProcessMessage(NetMsgType::VERACK, verackMessage); | |||||
BOOST_CHECK_EQUAL(ret, false); | |||||
return; | |||||
} | |||||
if (strCommand == NetMsgType::ADDR) { | |||||
// addrs starts with 1 entry. Only need to add ADDR_SOFT_CAP - 1 | |||||
std::vector<CAddress> sendAddrs(ADDR_SOFT_CAP - 1, addrs[0]); | |||||
CDataStream addrMessage = CreateAddrMessage(sendAddrs); | |||||
// Happy path | |||||
// Maximum number of addrs is ADDR_SOFT_CAP. All addrs are added | |||||
// until the ADDR_SOFT_CAPth. | |||||
BOOST_CHECK_EQUAL(1, addrs.size()); | |||||
bool ret = | |||||
CSeederNode::ProcessMessage(NetMsgType::ADDR, addrMessage); | |||||
BOOST_CHECK_EQUAL(ret, false); | |||||
BOOST_CHECK_EQUAL(ADDR_SOFT_CAP, addrs.size()); | |||||
// Test the seeder's addr softcap | |||||
// After the VADDR_SOFT_CAPth, only one is added and the rest are | |||||
// ignored | |||||
addrMessage = CreateAddrMessage(sendAddrs); | |||||
ret = CSeederNode::ProcessMessage(NetMsgType::ADDR, addrMessage); | |||||
BOOST_CHECK_EQUAL(ret, true); | |||||
BOOST_CHECK_EQUAL(ADDR_SOFT_CAP + 1, addrs.size()); | |||||
return; | |||||
} | |||||
} | |||||
}; | |||||
struct SeederTestingSetup { | |||||
SeederTestingSetup() { | |||||
CNetAddr ip; | |||||
ip.SetInternal("bitcoin.test"); | |||||
service = {ip, SERVICE_PORT}; | |||||
vAddr.emplace_back(service, ServiceFlags()); | |||||
testNode = std::make_unique<TestCSeederNode>(service, &vAddr); | |||||
} | |||||
std::vector<CAddress> vAddr; | |||||
CService service; | |||||
std::unique_ptr<TestCSeederNode> testNode; | |||||
}; | |||||
BOOST_FIXTURE_TEST_SUITE(seeder_tests, SeederTestingSetup) | |||||
BOOST_AUTO_TEST_CASE(seeder_node_version_test) { | |||||
testNode->TestProcessMessage(NetMsgType::VERSION, vAddr); | |||||
} | |||||
BOOST_AUTO_TEST_CASE(seeder_node_verack_test) { | |||||
testNode->TestProcessMessage(NetMsgType::VERACK, vAddr); | |||||
} | |||||
BOOST_AUTO_TEST_CASE(test_stub) { | BOOST_AUTO_TEST_CASE(seeder_node_addr_test) { | ||||
BOOST_CHECK_EQUAL(true, true); | testNode->TestProcessMessage(NetMsgType::ADDR, vAddr); | ||||
} | } | ||||
BOOST_AUTO_TEST_SUITE_END() | BOOST_AUTO_TEST_SUITE_END() |