diff --git a/src/seeder/bitcoin.h b/src/seeder/bitcoin.h index 2536783b0..e49e67f86 100644 --- a/src/seeder/bitcoin.h +++ b/src/seeder/bitcoin.h @@ -1,77 +1,77 @@ // Copyright (c) 2017-2019 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_SEEDER_BITCOIN_H #define BITCOIN_SEEDER_BITCOIN_H #include #include #include #include #include static inline unsigned short GetDefaultPort() { return Params().GetDefaultPort(); } // The network magic to use. extern CMessageHeader::MessageMagic netMagic; -enum PeerMessagingState : bool { - AwaitingMessages = false, - Finished = true, +enum class PeerMessagingState { + AwaitingMessages, + Finished, }; class CSeederNode { private: SOCKET sock; CDataStream vSend; CDataStream vRecv; uint32_t nHeaderStart; uint32_t nMessageStart; int nVersion; std::string strSubVer; int nStartingHeight; std::vector *vAddr; int ban; int64_t doneAfter; CAddress you; int GetTimeout() { return you.IsTor() ? 120 : 30; } void BeginMessage(const char *pszCommand); void AbortMessage(); void EndMessage(); void Send(); void PushVersion(); bool ProcessMessages(); protected: PeerMessagingState ProcessMessage(std::string strCommand, CDataStream &recv); public: CSeederNode(const CService &ip, std::vector *vAddrIn); bool Run(); int GetBan() { return ban; } int GetClientVersion() { return nVersion; } std::string GetClientSubVersion() { return strSubVer; } int GetStartingHeight() { return nStartingHeight; } }; bool TestNode(const CService &cip, int &ban, int &client, std::string &clientSV, int &blocks, std::vector *vAddr); #endif // BITCOIN_SEEDER_BITCOIN_H diff --git a/src/seeder/test/p2p_messaging_tests.cpp b/src/seeder/test/p2p_messaging_tests.cpp index a8c75d617..35261c689 100644 --- a/src/seeder/test/p2p_messaging_tests.cpp +++ b/src/seeder/test/p2p_messaging_tests.cpp @@ -1,135 +1,142 @@ // Copyright (c) 2019 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #define BOOST_TEST_MODULE Bitcoin Seeder Test Suite #include #include #include #include +#include #include #include #include #include #include +#include #include #include const std::function G_TRANSLATION_FUN = nullptr; #include +std::ostream &operator<<(std::ostream &os, const PeerMessagingState &state) { + os << to_integral(state); + return os; +} + class TestCSeederNode : public CSeederNode { public: TestCSeederNode(const CService &service, std::vector *vAddrIn) : CSeederNode(service, vAddrIn) { SelectParams(CBaseChainParams::REGTEST); } void TestProcessMessage(const std::string &strCommand, CDataStream &message, PeerMessagingState expectedState) { PeerMessagingState ret = CSeederNode::ProcessMessage(strCommand, message); BOOST_CHECK_EQUAL(ret, expectedState); } }; static const unsigned short SERVICE_PORT = 18444; struct SeederTestingSetup { SeederTestingSetup() { CNetAddr ip; ip.SetInternal("bitcoin.test"); CService service = {ip, SERVICE_PORT}; vAddr.emplace_back(service, ServiceFlags()); testNode = std::make_unique(service, &vAddr); } std::vector vAddr; std::unique_ptr testNode; }; BOOST_FIXTURE_TEST_SUITE(p2p_messaging_tests, SeederTestingSetup) static CDataStream CreateVersionMessage(int64_t now, CAddress addrTo, CAddress addrFrom, int32_t start_height, uint32_t nVersion, uint64_t nonce = 0, std::string user_agent = "/bitcoin-cash-seeder:0.15/") { CDataStream payload(SER_NETWORK, 0); payload.SetVersion(nVersion); ServiceFlags serviceflags = ServiceFlags(NODE_NETWORK); payload << nVersion << uint64_t(serviceflags) << now << addrTo << addrFrom << nonce << user_agent << start_height; return payload; } static const int SEEDER_INIT_VERSION = 0; BOOST_AUTO_TEST_CASE(seeder_node_version_test) { CService serviceFrom; CAddress addrFrom(serviceFrom, ServiceFlags(NODE_NETWORK | NODE_BITCOIN_CASH)); CDataStream versionMessage = CreateVersionMessage(time(nullptr), vAddr[0], addrFrom, GetRequireHeight(), INIT_PROTO_VERSION); // Verify the version is set as the initial value BOOST_CHECK_EQUAL(testNode->CSeederNode::GetClientVersion(), SEEDER_INIT_VERSION); testNode->TestProcessMessage(NetMsgType::VERSION, versionMessage, PeerMessagingState::AwaitingMessages); // Verify the version has been updated BOOST_CHECK_EQUAL(testNode->CSeederNode::GetClientVersion(), versionMessage.GetVersion()); } static CDataStream CreateAddrMessage(std::vector sendAddrs, uint32_t nVersion = INIT_PROTO_VERSION) { CDataStream payload(SER_NETWORK, 0); payload.SetVersion(nVersion); payload << sendAddrs; return payload; } // After the 1000th addr, the seeder will only add one more address per addr // message. static const int ADDR_SOFT_CAP = 1000; BOOST_AUTO_TEST_CASE(seeder_node_addr_test) { // vAddrs starts with 1 entry. std::vector sendAddrs(ADDR_SOFT_CAP - 1, vAddr[0]); // Happy path // addrs are added normally to vAddr until ADDR_SOFT_CAP is reached. // Add addrs up to the soft cap. CDataStream addrMessage = CreateAddrMessage(sendAddrs); BOOST_CHECK_EQUAL(1, vAddr.size()); testNode->TestProcessMessage(NetMsgType::ADDR, addrMessage, PeerMessagingState::AwaitingMessages); BOOST_CHECK_EQUAL(ADDR_SOFT_CAP, vAddr.size()); // ADDR_SOFT_CAP is exceeded sendAddrs.resize(1); addrMessage = CreateAddrMessage(sendAddrs); testNode->TestProcessMessage(NetMsgType::ADDR, addrMessage, PeerMessagingState::Finished); BOOST_CHECK_EQUAL(ADDR_SOFT_CAP + 1, vAddr.size()); // Test the seeder's behavior after ADDR_SOFT_CAP addrs // Only one addr per ADDR message will be added, the rest are ignored size_t expectedSize = vAddr.size() + 1; for (size_t i = 1; i < 10; i++) { sendAddrs.resize(i, sendAddrs[0]); addrMessage = CreateAddrMessage(sendAddrs); testNode->TestProcessMessage(NetMsgType::ADDR, addrMessage, PeerMessagingState::Finished); BOOST_CHECK_EQUAL(expectedSize, vAddr.size()); ++expectedSize; } } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/seeder/test/util.h b/src/seeder/test/util.h new file mode 100644 index 000000000..e1b9c74e8 --- /dev/null +++ b/src/seeder/test/util.h @@ -0,0 +1,15 @@ +// Copyright (c) 2020 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_SEEDER_TEST_UTIL_H +#define BITCOIN_SEEDER_TEST_UTIL_H + +#include + +template +constexpr typename std::underlying_type::type to_integral(E e) { + return static_cast::type>(e); +} + +#endif // BITCOIN_SEEDER_TEST_UTIL_H