Bitcoin ABC  0.24.7
P2P Digital Currency
p2p_messaging_tests.cpp
Go to the documentation of this file.
1 // Copyright (c) 2019 The Bitcoin developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <chainparams.h>
6 #include <protocol.h>
7 #include <seeder/bitcoin.h>
8 #include <seeder/db.h>
9 #include <seeder/test/util.h>
10 #include <serialize.h>
11 #include <streams.h>
12 #include <util/system.h>
13 #include <version.h>
14 
15 #include <boost/test/unit_test.hpp>
16 
17 #include <cstdint>
18 #include <memory>
19 #include <ostream>
20 #include <string>
21 #include <vector>
22 
23 std::ostream &operator<<(std::ostream &os, const PeerMessagingState &state) {
24  os << to_integral(state);
25  return os;
26 }
27 
28 namespace {
29 class CSeederNodeTest : public CSeederNode {
30 public:
31  CSeederNodeTest(const CService &service, std::vector<CAddress> *vAddrIn)
32  : CSeederNode(service, vAddrIn) {}
33 
34  void TestProcessMessage(const std::string &strCommand, CDataStream &message,
35  PeerMessagingState expectedState) {
36  PeerMessagingState ret = ProcessMessage(strCommand, message);
37  BOOST_CHECK_EQUAL(ret, expectedState);
38  }
39 
40  CDataStream getSendBuffer() { return vSend; }
41 };
42 } // namespace
43 
44 static const uint16_t SERVICE_PORT = 18444;
45 
49  CNetAddr ip;
50  ip.SetInternal("bitcoin.test");
51  CService service = {ip, SERVICE_PORT};
52  vAddr.emplace_back(service, ServiceFlags());
53  testNode = std::make_unique<CSeederNodeTest>(service, &vAddr);
54  }
55 
56  std::vector<CAddress> vAddr;
57  std::unique_ptr<CSeederNodeTest> testNode;
58 };
59 
60 BOOST_FIXTURE_TEST_SUITE(p2p_messaging_tests, SeederTestingSetup)
61 
62 static CDataStream
63 CreateVersionMessage(int64_t now, CAddress addrTo, CAddress addrFrom,
64  int32_t start_height, uint32_t nVersion,
65  uint64_t nonce = 0,
66  std::string user_agent = "/Bitcoin ABC:0.0.0(seeder)/") {
67  CDataStream payload(SER_NETWORK, 0);
68  payload.SetVersion(nVersion);
69  ServiceFlags serviceflags = ServiceFlags(NODE_NETWORK);
70  payload << nVersion << uint64_t(serviceflags) << now << addrTo << addrFrom
71  << nonce << user_agent << start_height;
72  return payload;
73 }
74 
75 static const int SEEDER_INIT_VERSION = 0;
76 
77 BOOST_AUTO_TEST_CASE(process_version_msg) {
78  CService serviceFrom;
79  CAddress addrFrom(serviceFrom, ServiceFlags(NODE_NETWORK));
80 
81  CDataStream versionMessage = CreateVersionMessage(
82  GetTime(), vAddr[0], addrFrom, GetRequireHeight(), INIT_PROTO_VERSION);
83 
84  // Verify the version is set as the initial value
85  BOOST_CHECK_EQUAL(testNode->CSeederNode::GetClientVersion(),
87  testNode->TestProcessMessage(NetMsgType::VERSION, versionMessage,
89  // Verify the version has been updated
90  BOOST_CHECK_EQUAL(testNode->CSeederNode::GetClientVersion(),
91  versionMessage.GetVersion());
92 }
93 
94 BOOST_AUTO_TEST_CASE(process_verack_msg) {
95  CDataStream verackMessage(SER_NETWORK, 0);
96  verackMessage.SetVersion(INIT_PROTO_VERSION);
97  testNode->TestProcessMessage(NetMsgType::VERACK, verackMessage,
99 
100  // Seeder should respond with an ADDR message
101  const CMessageHeader::MessageMagic netMagic = Params().NetMagic();
102  CMessageHeader header(netMagic);
103  CDataStream sendBuffer = testNode->getSendBuffer();
104  sendBuffer >> header;
105  BOOST_CHECK(header.IsValidWithoutConfig(netMagic));
106  BOOST_CHECK_EQUAL(header.GetCommand(), NetMsgType::GETADDR);
107 
108  // Next message should be GETHEADERS
109  sendBuffer >> header;
110  BOOST_CHECK(header.IsValidWithoutConfig(netMagic));
111  BOOST_CHECK_EQUAL(header.GetCommand(), NetMsgType::GETHEADERS);
112 
113  CBlockLocator locator;
114  uint256 hashStop;
115  sendBuffer >> locator >> hashStop;
116  std::vector<BlockHash> expectedLocator = {
117  Params().Checkpoints().mapCheckpoints.rbegin()->second};
118  BOOST_CHECK(locator.vHave == expectedLocator);
119  BOOST_CHECK(hashStop == uint256());
120 }
121 
122 static CDataStream CreateAddrMessage(std::vector<CAddress> sendAddrs,
123  uint32_t nVersion = INIT_PROTO_VERSION) {
124  CDataStream payload(SER_NETWORK, 0);
125  payload.SetVersion(nVersion);
126  payload << sendAddrs;
127  return payload;
128 }
129 
130 BOOST_AUTO_TEST_CASE(process_addr_msg) {
131  // vAddrs starts with 1 entry.
132  std::vector<CAddress> sendAddrs(ADDR_SOFT_CAP - 1, vAddr[0]);
133 
134  // Happy path
135  // addrs are added normally to vAddr until ADDR_SOFT_CAP is reached.
136  // Add addrs up to the soft cap.
137  CDataStream addrMessage = CreateAddrMessage(sendAddrs);
138  BOOST_CHECK_EQUAL(1, vAddr.size());
139  testNode->TestProcessMessage(NetMsgType::ADDR, addrMessage,
141  BOOST_CHECK_EQUAL(ADDR_SOFT_CAP, vAddr.size());
142 
143  // ADDR_SOFT_CAP is exceeded
144  sendAddrs.resize(1);
145  addrMessage = CreateAddrMessage(sendAddrs);
146  testNode->TestProcessMessage(NetMsgType::ADDR, addrMessage,
148  BOOST_CHECK_EQUAL(ADDR_SOFT_CAP + 1, vAddr.size());
149 
150  // Test the seeder's behavior after ADDR_SOFT_CAP addrs
151  // Only one addr per ADDR message will be added, the rest are ignored
152  size_t expectedSize = vAddr.size() + 1;
153  for (size_t i = 1; i < 10; i++) {
154  sendAddrs.resize(i, sendAddrs[0]);
155  addrMessage = CreateAddrMessage(sendAddrs);
156  testNode->TestProcessMessage(NetMsgType::ADDR, addrMessage,
158  BOOST_CHECK_EQUAL(expectedSize, vAddr.size());
159  ++expectedSize;
160  }
161 }
162 
SEEDER_INIT_VERSION
static const int SEEDER_INIT_VERSION
Definition: p2p_messaging_tests.cpp:75
CService
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:514
PeerMessagingState::AwaitingMessages
@ AwaitingMessages
CreateVersionMessage
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 ABC:0.0.0(seeder)/")
Definition: p2p_messaging_tests.cpp:63
streams.h
CNetAddr
Network address.
Definition: netaddress.h:117
CBlockLocator::vHave
std::vector< BlockHash > vHave
Definition: block.h:101
SeederTestingSetup::testNode
std::unique_ptr< CSeederNodeTest > testNode
Definition: p2p_messaging_tests.cpp:57
GetTime
int64_t GetTime()
DEPRECATED Use either GetSystemTimeInSeconds (not mockable) or GetTime<T> (mockable)
Definition: time.cpp:27
GetRequireHeight
static int GetRequireHeight()
Definition: db.h:28
ServiceFlags
ServiceFlags
nServices flags.
Definition: protocol.h:314
CCheckpointData::mapCheckpoints
MapCheckpoints mapCheckpoints
Definition: chainparams.h:25
NODE_NETWORK
@ NODE_NETWORK
Definition: protocol.h:321
chainparams.h
BOOST_FIXTURE_TEST_SUITE
#define BOOST_FIXTURE_TEST_SUITE(a, b)
Definition: object.cpp:14
CSeederNode::vSend
CDataStream vSend
Definition: bitcoin.h:38
version.h
db.h
SER_NETWORK
@ SER_NETWORK
Definition: serialize.h:165
testNode
static NodeContext testNode
Definition: coinselector_tests.cpp:36
ADDR_SOFT_CAP
static const unsigned int ADDR_SOFT_CAP
Definition: bitcoin.h:22
CSeederNode::ProcessMessage
PeerMessagingState ProcessMessage(std::string strCommand, CDataStream &recv)
Definition: bitcoin.cpp:38
NetMsgType::GETHEADERS
const char * GETHEADERS
The getheaders message requests a headers message that provides block headers starting from a particu...
Definition: protocol.cpp:27
bitcoin.h
to_integral
constexpr std::underlying_type< E >::type to_integral(E e)
Definition: util.h:11
CBaseChainParams::REGTEST
static const std::string REGTEST
Definition: chainparamsbase.h:23
PeerMessagingState::Finished
@ Finished
SelectParams
void SelectParams(const std::string &network)
Sets the params returned by Params() to those for the given BIP70 chain name.
Definition: chainparams.cpp:530
PeerMessagingState
PeerMessagingState
Definition: bitcoin.h:24
uint256
256-bit opaque blob.
Definition: uint256.h:127
CDataStream::SetVersion
void SetVersion(int n)
Definition: streams.h:386
NetMsgType::ADDR
const char * ADDR
The addr (IP address) message relays connection information for peers on the network.
Definition: protocol.cpp:20
util.h
system.h
SeederTestingSetup::vAddr
std::vector< CAddress > vAddr
Definition: p2p_messaging_tests.cpp:56
CDataStream::GetVersion
int GetVersion() const
Definition: streams.h:387
CAddress
A CService with information about it as peer.
Definition: protocol.h:421
CMessageHeader
Message header.
Definition: protocol.h:37
CChainParams::Checkpoints
const CCheckpointData & Checkpoints() const
Definition: chainparams.h:93
CMessageHeader::MessageMagic
std::array< uint8_t, MESSAGE_START_SIZE > MessageMagic
Definition: protocol.h:49
CSeederNode
Definition: bitcoin.h:33
Params
const CChainParams & Params()
Return the currently selected parameters.
Definition: chainparams.cpp:508
SeederTestingSetup
Definition: p2p_messaging_tests.cpp:46
serialize.h
CDataStream
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:197
NetMsgType::VERACK
const char * VERACK
The verack message acknowledges a previously-received version message, informing the connecting node ...
Definition: protocol.cpp:19
CNetAddr::SetInternal
bool SetInternal(const std::string &name)
Create an "internal" address that represents a name or FQDN.
Definition: netaddress.cpp:188
SeederTestingSetup::SeederTestingSetup
SeederTestingSetup()
Definition: p2p_messaging_tests.cpp:47
operator<<
std::ostream & operator<<(std::ostream &os, const PeerMessagingState &state)
Definition: p2p_messaging_tests.cpp:23
CreateAddrMessage
static CDataStream CreateAddrMessage(std::vector< CAddress > sendAddrs, uint32_t nVersion=INIT_PROTO_VERSION)
Definition: p2p_messaging_tests.cpp:122
CBlockLocator
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
Definition: block.h:100
NetMsgType::VERSION
const char * VERSION
The version message provides information about the transmitting node to the receiving node at the beg...
Definition: protocol.cpp:18
CChainParams::NetMagic
const CMessageHeader::MessageMagic & NetMagic() const
Definition: chainparams.h:61
BOOST_CHECK
#define BOOST_CHECK(expr)
Definition: object.cpp:17
BOOST_AUTO_TEST_SUITE_END
#define BOOST_AUTO_TEST_SUITE_END()
Definition: object.cpp:16
BOOST_CHECK_EQUAL
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:18
SERVICE_PORT
static const uint16_t SERVICE_PORT
Definition: p2p_messaging_tests.cpp:44
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(process_version_msg)
Definition: p2p_messaging_tests.cpp:77
NetMsgType::GETADDR
const char * GETADDR
The getaddr message requests an addr message from the receiving node, preferably one with lots of IP ...
Definition: protocol.cpp:31
INIT_PROTO_VERSION
static const int INIT_PROTO_VERSION
initial proto version, to be increased after version/verack negotiation
Definition: version.h:14