Bitcoin ABC 0.26.3
P2P Digital Currency
Loading...
Searching...
No Matches
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 <common/system.h>
7#include <net_processing.h>
8#include <protocol.h>
9#include <seeder/bitcoin.h>
10#include <seeder/db.h>
11#include <seeder/test/util.h>
12#include <serialize.h>
13#include <streams.h>
14#include <version.h>
15
16#include <boost/test/unit_test.hpp>
17
18#include <cstdint>
19#include <memory>
20#include <ostream>
21#include <string>
22#include <vector>
23
24std::ostream &operator<<(std::ostream &os, const PeerMessagingState &state) {
25 os << to_integral(state);
26 return os;
27}
28
29namespace {
30class CSeederNodeTest : public CSeederNode {
31public:
32 CSeederNodeTest(const CService &service, std::vector<CAddress> *vAddrIn)
33 : CSeederNode(service, vAddrIn) {}
34
35 void TestProcessMessage(const std::string &strCommand, CDataStream &message,
39 }
40
41 CDataStream getSendBuffer() { return vSend; }
42
44 nStartingHeight = starting_height;
45 };
46};
47} // namespace
48
49static const uint16_t SERVICE_PORT = 18444;
50
52 SeederTestingSetup(const std::string chain = CBaseChainParams::REGTEST) {
53 SelectParams(chain);
54 CNetAddr ip;
55 ip.SetInternal("bitcoin.test");
56 CService service = {ip, SERVICE_PORT};
57 vAddr.emplace_back(service, ServiceFlags());
58 testNode = std::make_unique<CSeederNodeTest>(service, &vAddr);
59 }
60
61 std::vector<CAddress> vAddr;
62 std::unique_ptr<CSeederNodeTest> testNode;
63};
64
68
70
72
76 CService addr_to = vAddr[0];
77 uint64_t addr_to_services = vAddr[0].nServices;
79 uint64_t nonce = 0;
80 std::string user_agent = "/Bitcoin ABC:0.0.0(seeder)/";
81
82 // Don't include the time in CAddress serialization. See D14753.
85 << nonce << user_agent << GetRequireHeight();
86
87 // Verify the version is set as the initial value
88 BOOST_CHECK_EQUAL(testNode->CSeederNode::GetClientVersion(),
90 testNode->TestProcessMessage(NetMsgType::VERSION, versionMessage,
92 // Verify the version has been updated
93 BOOST_CHECK_EQUAL(testNode->CSeederNode::GetClientVersion(),
94 versionMessage.GetVersion());
95}
96
100 testNode->TestProcessMessage(NetMsgType::VERACK, verackMessage,
102
103 // Seeder should respond with an ADDR message
104 const CMessageHeader::MessageMagic netMagic = Params().NetMagic();
105 CMessageHeader header(netMagic);
106 CDataStream sendBuffer = testNode->getSendBuffer();
107 sendBuffer >> header;
108 BOOST_CHECK(header.IsValidWithoutConfig(netMagic));
110
111 // Next message should be GETHEADERS
112 sendBuffer >> header;
113 BOOST_CHECK(header.IsValidWithoutConfig(netMagic));
115
119 std::vector<BlockHash> expectedLocator = {
120 Params().Checkpoints().mapCheckpoints.rbegin()->second};
123}
124
125static CDataStream CreateAddrMessage(std::vector<CAddress> sendAddrs,
126 uint32_t nVersion = INIT_PROTO_VERSION) {
128 payload.SetVersion(nVersion);
130 return payload;
131}
132
134 // First, must send headers to satisfy the criteria that both ADDR/ADDRV2
135 // *and* HEADERS must arrive before TestNode can advance to the Finished
136 // state
138 ::Params().Checkpoints().mapCheckpoints.rbegin()->second;
140 ::Params().Checkpoints().mapCheckpoints.rbegin()->first;
141 auto header = CBlockHeader{};
143 testNode->setStartingHeight(recentCheckpointHeight + 1);
145 headersMsg.SetVersion(INIT_PROTO_VERSION);
147 headersMsg << header;
148 // sanity check: node is expecting headers
149 BOOST_CHECK(!testNode->IsCheckpointVerified());
150 testNode->TestProcessMessage(NetMsgType::HEADERS, headersMsg,
152 BOOST_CHECK_EQUAL(testNode->GetBan(), 0);
153 // node got the checkpointed header; it can advance to Finished after
154 // addr message
155 BOOST_CHECK(testNode->IsCheckpointVerified());
156
157 // vAddrs starts with 1 entry.
158 std::vector<CAddress> sendAddrs(ADDR_SOFT_CAP - 1, vAddr[0]);
159
160 // Happy path
161 // addrs are added normally to vAddr until ADDR_SOFT_CAP is reached.
162 // Add addrs up to the soft cap.
164 BOOST_CHECK_EQUAL(1, vAddr.size());
165 testNode->TestProcessMessage(NetMsgType::ADDR, addrMessage,
167 BOOST_CHECK_EQUAL(ADDR_SOFT_CAP, vAddr.size());
168
169 // ADDR_SOFT_CAP is exceeded
170 sendAddrs.resize(1);
172 testNode->TestProcessMessage(NetMsgType::ADDR, addrMessage,
174 BOOST_CHECK_EQUAL(ADDR_SOFT_CAP + 1, vAddr.size());
175
176 // Test the seeder's behavior after ADDR_SOFT_CAP addrs
177 // Only one addr per ADDR message will be added, the rest are ignored
178 size_t expectedSize = vAddr.size() + 1;
179 for (size_t i = 1; i < 10; i++) {
180 sendAddrs.resize(i, sendAddrs[0]);
182 testNode->TestProcessMessage(NetMsgType::ADDR, addrMessage,
184 BOOST_CHECK_EQUAL(expectedSize, vAddr.size());
185 ++expectedSize;
186 }
187}
188
190 // Process the maximum number of headers
191 auto header = CBlockHeader{};
195 for (size_t i = 0; i < MAX_HEADERS_RESULTS; i++) {
196 maxHeaderMessages << header;
198 }
201 BOOST_CHECK_EQUAL(testNode->GetBan(), 0);
202
203 // Process one too many headers
207 // The message processing will abort when seeing the excessive number of
208 // headers from the compact size. No need to actually pack any header data.
211 BOOST_CHECK(testNode->GetBan() > 0);
212}
213
215 // Check that an empty headers message does not cause issues
221 BOOST_CHECK_EQUAL(testNode->GetBan(), 0);
222}
223
226 ::Params().Checkpoints().mapCheckpoints.rbegin()->second;
228 ::Params().Checkpoints().mapCheckpoints.rbegin()->first;
229
230 // Process a HEADERS message with a first header that immediately follows
231 // our most recent checkpoint, check that it is accepted.
232 auto header = CBlockHeader{};
234 testNode->setStartingHeight(recentCheckpointHeight + 1);
238 headersOnCorrectChain << header;
241 BOOST_CHECK_EQUAL(testNode->GetBan(), 0);
242 BOOST_CHECK(testNode->IsCheckpointVerified());
243}
244
247 ::Params().Checkpoints().mapCheckpoints.rbegin()->second;
249 ::Params().Checkpoints().mapCheckpoints.rbegin()->first;
250 auto header = CBlockHeader{};
251
252 // We just ignore HEADERS messages sent by nodes with a chaintip before our
253 // most recent checkpoint.
254 testNode->setStartingHeight(recentCheckpointHeight - 1);
258 shortHeaderChain << header;
259 testNode->TestProcessMessage(NetMsgType::HEADERS, shortHeaderChain,
261 BOOST_CHECK_EQUAL(testNode->GetBan(), 0);
262 BOOST_CHECK(!testNode->IsCheckpointVerified());
263
264 // Process a HEADERS message with a first header that does not follow
265 // our most recent checkpoint, check that the node is banned.
266 BOOST_CHECK(header.hashPrevBlock != recentCheckpoint);
267 testNode->setStartingHeight(recentCheckpointHeight + 1);
271 headersOnWrongChain << header;
274 BOOST_CHECK(testNode->GetBan() > 0);
275 BOOST_CHECK(!testNode->IsCheckpointVerified());
276}
277
void SelectParams(const std::string &network)
Sets the params returned by Params() to those for the given BIP70 chain name.
const CChainParams & Params()
Return the currently selected parameters.
CBaseChainParams defines the base parameters (shared between bitcoin-cli and bitcoind) of a given ins...
static const std::string REGTEST
Nodes collect new transactions into a block, hash them into a hash tree, and scan through nonce value...
Definition block.h:23
BlockHash hashPrevBlock
Definition block.h:27
const CMessageHeader::MessageMagic & NetMagic() const
Definition chainparams.h:94
const CCheckpointData & Checkpoints() const
Double ended buffer combining vector and stream-like interfaces.
Definition streams.h:177
Message header.
Definition protocol.h:34
bool IsValidWithoutConfig(const MessageMagic &magic) const
This is a transition method in order to stay compatible with older code that do not use the config.
Definition protocol.cpp:177
std::string GetCommand() const
Definition protocol.cpp:119
std::array< uint8_t, MESSAGE_START_SIZE > MessageMagic
Definition protocol.h:46
Network address.
Definition netaddress.h:121
bool SetInternal(const std::string &name)
Create an "internal" address that represents a name or FQDN.
CDataStream vSend
Definition bitcoin.h:42
friend class ::CSeederNodeTest
Definition bitcoin.h:38
PeerMessagingState ProcessMessage(std::string strCommand, CDataStream &recv)
Definition bitcoin.cpp:41
A combination of a network address (CNetAddr) and a (TCP) port.
Definition netaddress.h:545
256-bit opaque blob.
Definition uint256.h:129
static node::NodeContext testNode
const char * HEADERS
The headers message sends one or more block headers to a node which previously requested certain head...
Definition protocol.cpp:29
const char * GETADDR
The getaddr message requests an addr message from the receiving node, preferably one with lots of IP ...
Definition protocol.cpp:31
const char * ADDR
The addr (IP address) message relays connection information for peers on the network.
Definition protocol.cpp:20
const char * VERSION
The version message provides information about the transmitting node to the receiving node at the beg...
Definition protocol.cpp:18
const char * GETHEADERS
The getheaders message requests a headers message that provides block headers starting from a particu...
Definition protocol.cpp:27
const char * VERACK
The verack message acknowledges a previously-received version message, informing the connecting node ...
Definition protocol.cpp:19
static const unsigned int MAX_HEADERS_RESULTS
Number of headers sent in one getheaders result.
#define BOOST_CHECK_EQUAL(v1, v2)
Definition object.cpp:18
#define BOOST_CHECK(expr)
Definition object.cpp:17
static const uint16_t SERVICE_PORT
static CDataStream CreateAddrMessage(std::vector< CAddress > sendAddrs, uint32_t nVersion=INIT_PROTO_VERSION)
std::ostream & operator<<(std::ostream &os, const PeerMessagingState &state)
BOOST_FIXTURE_TEST_CASE(process_verack_msg, MainNetSeederTestingSetup)
BOOST_AUTO_TEST_CASE(process_version_msg)
static const int SEEDER_INIT_VERSION
ServiceFlags
nServices flags.
Definition protocol.h:335
@ NODE_NETWORK
Definition protocol.h:342
T GetRand(T nMax=std::numeric_limits< T >::max()) noexcept
Generate a uniform random integer of type T in the range [0..nMax) nMax defaults to std::numeric_limi...
Definition random.h:85
PeerMessagingState
Definition bitcoin.h:26
static const unsigned int ADDR_SOFT_CAP
Definition bitcoin.h:24
static int GetRequireHeight()
Definition db.h:28
constexpr std::underlying_type< E >::type to_integral(E e)
Definition util.h:11
@ SER_NETWORK
Definition serialize.h:152
void WriteCompactSize(CSizeComputer &os, uint64_t nSize)
Definition serialize.h:1254
A BlockHash is a unqiue identifier for a block.
Definition blockhash.h:13
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
Definition block.h:105
MapCheckpoints mapCheckpoints
Definition chainparams.h:34
std::vector< CAddress > vAddr
std::unique_ptr< CSeederNodeTest > testNode
SeederTestingSetup(const std::string chain=CBaseChainParams::REGTEST)
int64_t GetTime()
DEPRECATED Use either ClockType::now() or Now<TimePointType>() if a cast is needed.
Definition time.cpp:109
static const int INIT_PROTO_VERSION
initial proto version, to be increased after version/verack negotiation
Definition version.h:14