Bitcoin ABC  0.26.3
P2P Digital Currency
bitcoin.cpp
Go to the documentation of this file.
1 // Copyright (c) 2017-2020 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 <seeder/bitcoin.h>
6 
7 #include <chainparams.h>
8 #include <clientversion.h>
9 #include <common/args.h>
10 #include <hash.h>
11 #include <net_processing.h>
12 #include <netbase.h>
13 #include <primitives/blockhash.h>
14 #include <seeder/db.h>
15 #include <seeder/messagewriter.h>
16 #include <serialize.h>
17 #include <uint256.h>
18 #include <util/sock.h>
19 #include <util/time.h>
20 #include <validation.h>
21 
22 #include <algorithm>
23 
24 #define BITCOIN_SEED_NONCE 0x0539a019ca550825ULL
25 
27  if (!sock) {
28  return;
29  }
30  if (vSend.empty()) {
31  return;
32  }
33  int nBytes = sock->Send(&vSend[0], vSend.size(), 0);
34  if (nBytes > 0) {
35  vSend.erase(vSend.begin(), vSend.begin() + nBytes);
36  } else {
37  sock.reset();
38  }
39 }
40 
42  CDataStream &recv) {
43  // tfm::format(std::cout, "%s: RECV %s\n", ToString(you),
44  // strCommand);
45  if (strCommand == NetMsgType::VERSION) {
46  int64_t nTime;
47  CService addrMe;
48  uint64_t nNonce = 1;
49  uint64_t nServiceInt;
50  recv >> nVersion >> nServiceInt >> nTime;
51  yourServices = ServiceFlags(nServiceInt);
52  // Ignore the addrMe service bits sent by the peer
53  recv.ignore(8);
54  recv >> addrMe;
55 
56  // The version message includes information about the sending node
57  // which we don't use:
58  // - 8 bytes (service bits)
59  // - 16 bytes (ipv6 address)
60  // - 2 bytes (port)
61  recv.ignore(26);
62  recv >> nNonce;
63  recv >> strSubVer;
64  recv >> nStartingHeight;
65 
69  }
70 
71  if (strCommand == NetMsgType::VERACK) {
73  // tfm::format(std::cout, "\n%s: version %i\n", ToString(you),
74  // nVersion);
75  if (vAddr) {
77  std::vector<BlockHash> locatorHash(
78  1, Params().Checkpoints().mapCheckpoints.rbegin()->second);
80  CBlockLocator(std::move(locatorHash)),
81  uint256());
82  doneAfter = Now<NodeSeconds>() + GetTimeout();
83  } else {
84  doneAfter = Now<NodeSeconds>() + 1s;
85  }
87  }
88 
89  if (strCommand == NetMsgType::ADDR && vAddr) {
90  std::vector<CAddress> vAddrNew;
91  recv >> vAddrNew;
92  // tfm::format(std::cout, "%s: got %i addresses\n",
93  // ToString(you),
94  // (int)vAddrNew.size());
95  auto now = Now<NodeSeconds>();
96  std::vector<CAddress>::iterator it = vAddrNew.begin();
97  if (vAddrNew.size() > 1) {
98  if (TicksSinceEpoch<std::chrono::seconds>(doneAfter) == 0 ||
99  doneAfter > now + 1s) {
100  doneAfter = now + 1s;
101  }
102  }
103  while (it != vAddrNew.end()) {
104  CAddress &addr = *it;
105  // tfm::format(std::cout, "%s: got address %s\n",
106  // ToString(you),
107  // addr.ToString(), (int)(vAddr->size()));
108  it++;
109  if (addr.nTime <= NodeSeconds{100000000s} ||
110  addr.nTime > now + 10min) {
111  addr.nTime = now - 5 * 24h;
112  }
113  if (addr.nTime > now - 7 * 24h) {
114  vAddr->push_back(addr);
115  }
116  // tfm::format(std::cout, "%s: added address %s (#%i)\n",
117  // ToString(you),
118  // addr.ToString(), (int)(vAddr->size()));
119  if (vAddr->size() > ADDR_SOFT_CAP) {
120  doneAfter = NodeSeconds{1s};
122  }
123  }
125  }
126 
127  if (strCommand == NetMsgType::HEADERS) {
128  uint64_t nCount = ReadCompactSize(recv);
129  if (nCount == 0) {
130  // Empty HEADERS messages can be sent when the peer does not have
131  // enough chainwork.
133  }
134  if (nCount > MAX_HEADERS_RESULTS) {
135  ban = 100000;
137  }
138 
139  CBlockHeader header;
140  recv >> header;
141 
142  // If the peer has a chain longer than our last checkpoint, we expect
143  // that the first header it will send will be the one just after
144  // that checkpoint, as we claim to have the checkpoint as our starting
145  // height in the version message.
146  if (!Params().Checkpoints().mapCheckpoints.empty() &&
148  header.hashPrevBlock !=
149  Params().Checkpoints().mapCheckpoints.rbegin()->second) {
150  // This node is synced higher than the last checkpoint height but
151  // does not have the checkpoint block in its chain.
152  // This means it must be on the wrong chain. We treat these nodes
153  // the same as nodes with the wrong net magic.
154  // std::fprintf(stdout, "%s: BAD \"%s\" (wrong chain)\n",
155  // ToString(you).c_str(), strSubVer.c_str());
156 
157  ban = 100000;
159  }
160  }
161 
163 }
164 
166  if (vRecv.empty()) {
167  return false;
168  }
169 
170  const CMessageHeader::MessageMagic netMagic = Params().NetMagic();
171 
172  do {
173  CDataStream::iterator pstart = std::search(
174  vRecv.begin(), vRecv.end(), BEGIN(netMagic), END(netMagic));
175  uint32_t nHeaderSize =
177  if (vRecv.end() - pstart < nHeaderSize) {
178  if (vRecv.size() > nHeaderSize) {
179  vRecv.erase(vRecv.begin(), vRecv.end() - nHeaderSize);
180  }
181  break;
182  }
183  vRecv.erase(vRecv.begin(), pstart);
184  std::vector<std::byte> vHeaderSave(vRecv.begin(),
185  vRecv.begin() + nHeaderSize);
186  CMessageHeader hdr(netMagic);
187  vRecv >> hdr;
188  if (!hdr.IsValidWithoutConfig(netMagic)) {
189  // tfm::format(std::cout, "%s: BAD (invalid header)\n",
190  // ToString(you));
191  ban = 100000;
192  return true;
193  }
194  std::string strCommand = hdr.GetCommand();
195  unsigned int nMessageSize = hdr.nMessageSize;
196  if (nMessageSize > MAX_SIZE) {
197  // tfm::format(std::cout, "%s: BAD (message too large)\n",
198  // ToString(you));
199  ban = 100000;
200  return true;
201  }
202  if (nMessageSize > vRecv.size()) {
203  vRecv.insert(vRecv.begin(), vHeaderSave.begin(), vHeaderSave.end());
204  break;
205  }
206  if (vRecv.GetVersion() >= 209) {
207  uint256 hash = Hash(Span{vRecv}.first(nMessageSize));
208  if (memcmp(hash.begin(), hdr.pchChecksum,
210  continue;
211  }
212  }
213  std::vector<std::byte> vec{vRecv.begin(), vRecv.begin() + nMessageSize};
214  CDataStream vMsg(MakeUCharSpan(vec), vRecv.GetType(),
215  vRecv.GetVersion());
216  vRecv.ignore(nMessageSize);
217  if (ProcessMessage(strCommand, vMsg) == PeerMessagingState::Finished) {
218  return true;
219  }
220  // tfm::format(std::cout, "%s: done processing %s\n",
221  // ToString(you),
222  // strCommand);
223  } while (1);
224  return false;
225 }
226 
227 CSeederNode::CSeederNode(const CService &ip, std::vector<CAddress> *vAddrIn)
228  : vSend(SER_NETWORK, 0), vRecv(SER_NETWORK, 0), vAddr(vAddrIn), you(ip) {
229  if (GetTime() > 1329696000) {
230  vSend.SetVersion(209);
231  vRecv.SetVersion(209);
232  }
233 }
234 
236  // FIXME: This logic is duplicated with CConnman::ConnectNode for no
237  // good reason.
238  bool connected = false;
239  proxyType proxy;
240 
241  if (you.IsValid()) {
242  bool proxyConnectionFailed = false;
243 
244  if (GetProxy(you.GetNetwork(), proxy)) {
245  sock = CreateSock(proxy.proxy);
246  if (!sock) {
247  return false;
248  }
249  connected = ConnectThroughProxy(
250  proxy, you.ToStringIP(), you.GetPort(), *sock, nConnectTimeout,
251  proxyConnectionFailed);
252  } else {
253  // no proxy needed (none set for target network)
254  sock = CreateSock(you);
255  if (!sock) {
256  return false;
257  }
258  // no proxy needed (none set for target network)
259  connected =
261  }
262  }
263 
264  if (!connected) {
265  // tfm::format(std::cout, "Cannot connect to %s\n",
266  // ToString(you));
267  sock.reset();
268  return false;
269  }
270 
271  // Write version message
272  // Don't include the time in CAddress serialization. See D14753.
273  uint64_t nLocalServices = 0;
274  uint64_t nLocalNonce = BITCOIN_SEED_NONCE;
275  uint64_t your_services{yourServices};
276  uint64_t my_services{ServiceFlags(NODE_NETWORK)};
277  uint8_t fRelayTxs = 0;
278 
279  const std::string clientName = gArgs.GetArg("-uaclientname", CLIENT_NAME);
280  const std::string clientVersion =
281  gArgs.GetArg("-uaclientversion", FormatVersion(CLIENT_VERSION));
282  const std::string userAgent =
283  FormatUserAgent(clientName, clientVersion, {"seeder"});
284 
286  nLocalServices, GetTime(), your_services, you,
287  my_services, CService(), nLocalNonce, userAgent,
288  GetRequireHeight(), fRelayTxs);
289  Send();
290 
291  bool res = true;
292  NodeSeconds now;
293  while (now = Now<NodeSeconds>(),
294  ban == 0 &&
295  (TicksSinceEpoch<std::chrono::seconds>(doneAfter) == 0 ||
296  doneAfter > now) &&
297  sock) {
298  char pchBuf[0x10000];
299  fd_set fdsetRecv;
300  fd_set fdsetError;
301  FD_ZERO(&fdsetRecv);
302  FD_ZERO(&fdsetError);
303  FD_SET(sock->Get(), &fdsetRecv);
304  FD_SET(sock->Get(), &fdsetError);
305  struct timeval wa;
306  if (TicksSinceEpoch<std::chrono::seconds>(doneAfter) != 0) {
307  wa.tv_sec = (doneAfter - now).count();
308  wa.tv_usec = 0;
309  } else {
310  wa.tv_sec = GetTimeout().count();
311  wa.tv_usec = 0;
312  }
313  int ret =
314  select(sock->Get() + 1, &fdsetRecv, nullptr, &fdsetError, &wa);
315  if (ret != 1) {
316  if (TicksSinceEpoch<std::chrono::seconds>(doneAfter) == 0) {
317  res = false;
318  }
319  break;
320  }
321  int nBytes = sock->Recv(pchBuf, sizeof(pchBuf), 0);
322  int nPos = vRecv.size();
323  if (nBytes > 0) {
324  vRecv.resize(nPos + nBytes);
325  memcpy(&vRecv[nPos], pchBuf, nBytes);
326  } else if (nBytes == 0) {
327  // tfm::format(std::cout, "%s: BAD (connection closed
328  // prematurely)\n",
329  // ToString(you));
330  res = false;
331  break;
332  } else {
333  // tfm::format(std::cout, "%s: BAD (connection error)\n",
334  // ToString(you));
335  res = false;
336  break;
337  }
338  ProcessMessages();
339  Send();
340  }
341  if (!sock) {
342  res = false;
343  }
344  sock.reset();
345  return (ban == 0) && res;
346 }
ArgsManager gArgs
Definition: args.cpp:38
const CChainParams & Params()
Return the currently selected parameters.
Definition: chainparams.cpp:19
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: args.cpp:494
A CService with information about it as peer.
Definition: protocol.h:442
NodeSeconds nTime
Always included in serialization, except in the network format on INIT_PROTO_VERSION.
Definition: protocol.h:544
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
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:177
const_iterator begin() const
Definition: streams.h:219
void SetVersion(int n)
Definition: streams.h:338
int GetType() const
Definition: streams.h:337
int GetVersion() const
Definition: streams.h:339
iterator insert(iterator it, const value_type x)
Definition: streams.h:237
const_iterator end() const
Definition: streams.h:221
void ignore(int nSize)
Definition: streams.h:360
bool empty() const
Definition: streams.h:224
vector_type::iterator iterator
Definition: streams.h:193
void resize(size_type n, value_type c=value_type{})
Definition: streams.h:225
iterator erase(iterator it)
Definition: streams.h:281
size_type size() const
Definition: streams.h:223
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
static constexpr size_t CHECKSUM_SIZE
Definition: protocol.h:39
uint8_t pchChecksum[CHECKSUM_SIZE]
Definition: protocol.h:72
std::string GetCommand() const
Definition: protocol.cpp:119
uint32_t nMessageSize
Definition: protocol.h:71
std::array< uint8_t, MESSAGE_START_SIZE > MessageMagic
Definition: protocol.h:46
std::string ToStringIP() const
Definition: netaddress.cpp:628
bool IsValid() const
Definition: netaddress.cpp:479
enum Network GetNetwork() const
Definition: netaddress.cpp:551
CDataStream vRecv
Definition: bitcoin.h:43
CService you
Definition: bitcoin.h:50
CSeederNode(const CService &ip, std::vector< CAddress > *vAddrIn)
Definition: bitcoin.cpp:227
CDataStream vSend
Definition: bitcoin.h:42
bool Run()
Definition: bitcoin.cpp:235
int nStartingHeight
Definition: bitcoin.h:46
int nVersion
Definition: bitcoin.h:44
std::vector< CAddress > * vAddr
Definition: bitcoin.h:47
ServiceFlags yourServices
Definition: bitcoin.h:51
bool ProcessMessages()
Definition: bitcoin.cpp:165
std::string strSubVer
Definition: bitcoin.h:45
PeerMessagingState ProcessMessage(std::string strCommand, CDataStream &recv)
Definition: bitcoin.cpp:41
void Send()
Definition: bitcoin.cpp:26
std::chrono::seconds GetTimeout()
Definition: bitcoin.h:53
int ban
Definition: bitcoin.h:48
NodeSeconds doneAfter
Definition: bitcoin.h:49
std::unique_ptr< Sock > sock
Definition: bitcoin.h:41
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:545
uint16_t GetPort() const
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:93
uint8_t * begin()
Definition: uint256.h:85
CService proxy
Definition: netbase.h:40
256-bit opaque blob.
Definition: uint256.h:129
std::string FormatVersion(int nVersion)
std::string FormatUserAgent(const std::string &name, const std::string &version, const std::vector< std::string > &comments)
Format the subversion field according to BIP 14 spec.
static constexpr int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
Definition: clientversion.h:38
const std::string CLIENT_NAME
uint256 Hash(const T &in1)
Compute the 256-bit hash of an object.
Definition: hash.h:74
Block-chain checkpoints are compiled-in sanity checks.
Definition: checkpoints.cpp:9
static void WriteMessage(CDataStream &stream, std::string command, Args &&...args)
Definition: messagewriter.h:15
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
std::string userAgent(const Config &config)
Definition: net.cpp:3591
static const unsigned int MAX_HEADERS_RESULTS
Number of headers sent in one getheaders result.
bool GetProxy(enum Network net, proxyType &proxyInfoOut)
Definition: netbase.cpp:720
bool ConnectThroughProxy(const proxyType &proxy, const std::string &strDest, uint16_t port, const Sock &sock, int nTimeout, bool &outProxyConnectionFailed)
Connect to a specified destination service through a SOCKS5 proxy by first connecting to the SOCKS5 p...
Definition: netbase.cpp:763
bool ConnectSocketDirectly(const CService &addrConnect, const Sock &sock, int nTimeout, bool manual_connection)
Try to connect to the specified service on the specified socket.
Definition: netbase.cpp:634
std::function< std::unique_ptr< Sock >const CService &)> CreateSock
Socket factory.
Definition: netbase.cpp:620
int nConnectTimeout
Definition: netbase.cpp:37
ServiceFlags
nServices flags.
Definition: protocol.h:335
@ NODE_NETWORK
Definition: protocol.h:342
#define BITCOIN_SEED_NONCE
Definition: bitcoin.cpp:24
PeerMessagingState
Definition: bitcoin.h:26
static const unsigned int ADDR_SOFT_CAP
Definition: bitcoin.h:24
static int GetRequireHeight()
Definition: db.h:28
#define BEGIN(a)
Definition: util.h:10
#define END(a)
Definition: util.h:11
static constexpr uint64_t MAX_SIZE
The maximum size of a serialized object in bytes or number of elements (for eg vectors) when the size...
Definition: serialize.h:31
@ SER_NETWORK
Definition: serialize.h:152
uint64_t ReadCompactSize(Stream &is, bool range_check=true)
Decode a CompactSize-encoded variable-length integer.
Definition: serialize.h:413
size_t GetSerializeSize(const T &t, int nVersion=0)
Definition: serialize.h:1258
constexpr auto MakeUCharSpan(V &&v) -> decltype(UCharSpanCast(Span{std::forward< V >(v)}))
Like the Span constructor, but for (const) uint8_t member types only.
Definition: span.h:337
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
static int count
Definition: tests.c:31
int64_t GetTime()
Definition: time.cpp:109
std::chrono::time_point< NodeClock, std::chrono::seconds > NodeSeconds
Definition: time.h:25
static const int PROTOCOL_VERSION
network protocol versioning
Definition: version.h:11