Electroneum
p2p_protocol_defs.h
Go to the documentation of this file.
1 // Copyrights(c) 2017-2020, The Electroneum Project
2 // Copyrights(c) 2014-2019, The Monero Project
3 //
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without modification, are
7 // permitted provided that the following conditions are met:
8 //
9 // 1. Redistributions of source code must retain the above copyright notice, this list of
10 // conditions and the following disclaimer.
11 //
12 // 2. Redistributions in binary form must reproduce the above copyright notice, this list
13 // of conditions and the following disclaimer in the documentation and/or other
14 // materials provided with the distribution.
15 //
16 // 3. Neither the name of the copyright holder nor the names of its contributors may be
17 // used to endorse or promote products derived from this software without specific
18 // prior written permission.
19 //
20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
21 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
23 // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
28 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 //
30 // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
31 
32 #pragma once
33 
34 #include <boost/uuid/uuid.hpp>
35 #include <boost/serialization/version.hpp>
36 #include "serialization/keyvalue_serialization.h"
37 #include "net/net_utils_base.h"
38 #include "net/tor_address.h" // needed for serialization
39 #include "net/i2p_address.h" // needed for serialization
40 #include "misc_language.h"
41 #include "string_tools.h"
42 #include "time_helper.h"
43 #include "cryptonote_config.h"
44 #ifdef ALLOW_DEBUG_COMMANDS
45 #include "crypto/crypto.h"
46 #endif
47 
48 namespace nodetool
49 {
50  typedef boost::uuids::uuid uuid;
51  typedef uint64_t peerid_type;
52 
53  static inline std::string peerid_to_string(peerid_type peer_id)
54  {
55  std::ostringstream s;
56  s << std::hex << peer_id;
57  return epee::string_tools::pad_string(s.str(), 16, '0', true);
58  }
59 
60 #pragma pack (push, 1)
61 
63  {
64  uint32_t ip;
65  uint32_t port;
66 
67  BEGIN_KV_SERIALIZE_MAP()
68  KV_SERIALIZE(ip)
69  KV_SERIALIZE(port)
70  END_KV_SERIALIZE_MAP()
71  };
72 
73  template<typename AddressType>
75  {
76  AddressType adr;
78  int64_t last_seen;
79  uint32_t pruning_seed;
80  uint16_t rpc_port;
81 
82  BEGIN_KV_SERIALIZE_MAP()
83  KV_SERIALIZE(adr)
84  KV_SERIALIZE(id)
85  if (!is_store || this_ref.last_seen != 0)
86  KV_SERIALIZE_OPT(last_seen, (int64_t)0)
87  KV_SERIALIZE_OPT(pruning_seed, (uint32_t)0)
88  KV_SERIALIZE_OPT(rpc_port, (uint16_t)0)
89  END_KV_SERIALIZE_MAP()
90  };
91  typedef peerlist_entry_base<epee::net_utils::network_address> peerlist_entry;
92 
93  template<typename AddressType>
95  {
96  AddressType adr;
98  int64_t first_seen;
99 
100  BEGIN_KV_SERIALIZE_MAP()
101  KV_SERIALIZE(adr)
102  KV_SERIALIZE(id)
103  KV_SERIALIZE(first_seen)
104  END_KV_SERIALIZE_MAP()
105  };
106  typedef anchor_peerlist_entry_base<epee::net_utils::network_address> anchor_peerlist_entry;
107 
108  template<typename AddressType>
110  {
111  AddressType adr;
113  bool is_income;
114 
115  BEGIN_KV_SERIALIZE_MAP()
116  KV_SERIALIZE(adr)
117  KV_SERIALIZE(id)
118  KV_SERIALIZE(is_income)
119  END_KV_SERIALIZE_MAP()
120  };
121  typedef connection_entry_base<epee::net_utils::network_address> connection_entry;
122 
123 #pragma pack(pop)
124 
125  inline
126  std::string print_peerlist_to_string(const std::vector<peerlist_entry>& pl)
127  {
128  time_t now_time = 0;
129  time(&now_time);
130  std::stringstream ss;
131  ss << std::setfill ('0') << std::setw (8) << std::hex << std::noshowbase;
132  for(const peerlist_entry& pe: pl)
133  {
134  ss << pe.id << "\t" << pe.adr.str()
135  << " \trpc port " << (pe.rpc_port > 0 ? std::to_string(pe.rpc_port) : "-")
136  << " \tpruning seed " << pe.pruning_seed
137  << " \tlast_seen: " << (pe.last_seen == 0 ? std::string("never") : epee::misc_utils::get_time_interval_string(now_time - pe.last_seen))
138  << std::endl;
139  }
140  return ss.str();
141  }
142 
143 
145  {
146  BEGIN_KV_SERIALIZE_MAP()
147  KV_SERIALIZE(max_out_connection_count)
148  KV_SERIALIZE(max_in_connection_count)
149  KV_SERIALIZE(handshake_interval)
150  KV_SERIALIZE(packet_max_size)
151  KV_SERIALIZE(config_id)
152  END_KV_SERIALIZE_MAP()
153 
154  uint32_t max_out_connection_count;
155  uint32_t max_in_connection_count;
156  uint32_t connection_timeout;
157  uint32_t ping_connection_timeout;
158  uint32_t handshake_interval;
159  uint32_t packet_max_size;
160  uint32_t config_id;
161  uint32_t send_peerlist_sz;
162  };
163 
165  {
167  uint64_t local_time;
168  uint32_t my_port;
169  uint16_t rpc_port;
171 
172  BEGIN_KV_SERIALIZE_MAP()
173  KV_SERIALIZE_VAL_POD_AS_BLOB(network_id)
174  KV_SERIALIZE(peer_id)
175  KV_SERIALIZE(local_time)
176  KV_SERIALIZE(my_port)
177  KV_SERIALIZE_OPT(rpc_port, (uint16_t)(0))
178  END_KV_SERIALIZE_MAP()
179  };
180 
181 
182 #define P2P_COMMANDS_POOL_BASE 1000
183 
184  /************************************************************************/
185  /* */
186  /************************************************************************/
187  template<class t_playload_type>
189  {
190  const static int ID = P2P_COMMANDS_POOL_BASE + 1;
191 
192  struct request_t
193  {
195  t_playload_type payload_data;
196 
197  BEGIN_KV_SERIALIZE_MAP()
198  KV_SERIALIZE(node_data)
199  KV_SERIALIZE(payload_data)
200  END_KV_SERIALIZE_MAP()
201  };
202  typedef epee::misc_utils::struct_init<request_t> request;
203 
204  struct response_t
205  {
207  t_playload_type payload_data;
208  std::vector<peerlist_entry> local_peerlist_new;
209 
210  BEGIN_KV_SERIALIZE_MAP()
211  KV_SERIALIZE(node_data)
212  KV_SERIALIZE(payload_data)
213  if (is_store)
214  {
215  // saving: save both, so old and new peers can understand it
216  KV_SERIALIZE(local_peerlist_new)
217  std::vector<peerlist_entry_base<network_address_old>> local_peerlist;
218  for (const auto &p: this_ref.local_peerlist_new)
219  {
220  if (p.adr.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id())
221  {
222  const epee::net_utils::network_address &na = p.adr;
223  const epee::net_utils::ipv4_network_address &ipv4 = na.as<const epee::net_utils::ipv4_network_address>();
224  local_peerlist.push_back(peerlist_entry_base<network_address_old>({{ipv4.ip(), ipv4.port()}, p.id, p.last_seen, p.pruning_seed, p.rpc_port}));
225  }
226  else
227  MDEBUG("Not including in legacy peer list: " << p.adr.str());
228  }
229  epee::serialization::selector<is_store>::serialize_stl_container_pod_val_as_blob(local_peerlist, stg, hparent_section, "local_peerlist");
230  }
231  else
232  {
233  // loading: load old list only if there is no new one
234  if (!epee::serialization::selector<is_store>::serialize(this_ref.local_peerlist_new, stg, hparent_section, "local_peerlist_new"))
235  {
236  std::vector<peerlist_entry_base<network_address_old>> local_peerlist;
237  epee::serialization::selector<is_store>::serialize_stl_container_pod_val_as_blob(local_peerlist, stg, hparent_section, "local_peerlist");
238  for (const auto &p: local_peerlist)
239  ((response&)this_ref).local_peerlist_new.push_back(peerlist_entry({epee::net_utils::ipv4_network_address(p.adr.ip, p.adr.port), p.id, p.last_seen, p.pruning_seed, p.rpc_port}));
240  }
241  }
242  END_KV_SERIALIZE_MAP()
243  };
244  typedef epee::misc_utils::struct_init<response_t> response;
245  };
246 
247 
248  /************************************************************************/
249  /* */
250  /************************************************************************/
251  template<class t_playload_type>
253  {
254  const static int ID = P2P_COMMANDS_POOL_BASE + 2;
255 
256  struct request_t
257  {
258  t_playload_type payload_data;
259  BEGIN_KV_SERIALIZE_MAP()
260  KV_SERIALIZE(payload_data)
261  END_KV_SERIALIZE_MAP()
262  };
263  typedef epee::misc_utils::struct_init<request_t> request;
264 
265  struct response_t
266  {
267  uint64_t local_time;
268  t_playload_type payload_data;
269  std::vector<peerlist_entry> local_peerlist_new;
270 
271  BEGIN_KV_SERIALIZE_MAP()
272  KV_SERIALIZE(local_time)
273  KV_SERIALIZE(payload_data)
274  if (is_store)
275  {
276  // saving: save both, so old and new peers can understand it
277  KV_SERIALIZE(local_peerlist_new)
278  std::vector<peerlist_entry_base<network_address_old>> local_peerlist;
279  for (const auto &p: this_ref.local_peerlist_new)
280  {
281  if (p.adr.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id())
282  {
283  const epee::net_utils::network_address &na = p.adr;
284  const epee::net_utils::ipv4_network_address &ipv4 = na.as<const epee::net_utils::ipv4_network_address>();
285  local_peerlist.push_back(peerlist_entry_base<network_address_old>({{ipv4.ip(), ipv4.port()}, p.id, p.last_seen}));
286  }
287  else
288  MDEBUG("Not including in legacy peer list: " << p.adr.str());
289  }
290  epee::serialization::selector<is_store>::serialize_stl_container_pod_val_as_blob(local_peerlist, stg, hparent_section, "local_peerlist");
291  }
292  else
293  {
294  // loading: load old list only if there is no new one
295  if (!epee::serialization::selector<is_store>::serialize(this_ref.local_peerlist_new, stg, hparent_section, "local_peerlist_new"))
296  {
297  std::vector<peerlist_entry_base<network_address_old>> local_peerlist;
298  epee::serialization::selector<is_store>::serialize_stl_container_pod_val_as_blob(local_peerlist, stg, hparent_section, "local_peerlist");
299  for (const auto &p: local_peerlist)
300  ((response&)this_ref).local_peerlist_new.push_back(peerlist_entry({epee::net_utils::ipv4_network_address(p.adr.ip, p.adr.port), p.id, p.last_seen}));
301  }
302  }
303  END_KV_SERIALIZE_MAP()
304  };
305  typedef epee::misc_utils::struct_init<response_t> response;
306  };
307 
308  /************************************************************************/
309  /* */
310  /************************************************************************/
311 
313  {
314  /*
315  Used to make "callback" connection, to be sure that opponent node
316  have accessible connection point. Only other nodes can add peer to peerlist,
317  and ONLY in case when peer has accepted connection and answered to ping.
318  */
319  const static int ID = P2P_COMMANDS_POOL_BASE + 3;
320 
321 #define PING_OK_RESPONSE_STATUS_TEXT "OK"
322 
323  struct request_t
324  {
325  /*actually we don't need to send any real data*/
326 
327  BEGIN_KV_SERIALIZE_MAP()
328  END_KV_SERIALIZE_MAP()
329  };
330  typedef epee::misc_utils::struct_init<request_t> request;
331 
332  struct response_t
333  {
334  std::string status;
336 
337  BEGIN_KV_SERIALIZE_MAP()
338  KV_SERIALIZE(status)
339  KV_SERIALIZE(peer_id)
340  END_KV_SERIALIZE_MAP()
341  };
342  typedef epee::misc_utils::struct_init<response_t> response;
343  };
344 
345 
346 #ifdef ALLOW_DEBUG_COMMANDS
347  //These commands are considered as insecure, and made in debug purposes for a limited lifetime.
348  //Anyone who feel unsafe with this commands can disable the ALLOW_GET_STAT_COMMAND macro.
349 
350  struct proof_of_trust
351  {
352  peerid_type peer_id;
353  uint64_t time;
354  crypto::signature sign;
355 
356  BEGIN_KV_SERIALIZE_MAP()
357  KV_SERIALIZE(peer_id)
358  KV_SERIALIZE(time)
359  KV_SERIALIZE_VAL_POD_AS_BLOB(sign)
360  END_KV_SERIALIZE_MAP()
361  };
362 
363 
364  template<class payload_stat_info>
365  struct COMMAND_REQUEST_STAT_INFO_T
366  {
367  const static int ID = P2P_COMMANDS_POOL_BASE + 4;
368 
369  struct request_t
370  {
371  proof_of_trust tr;
372  BEGIN_KV_SERIALIZE_MAP()
373  KV_SERIALIZE(tr)
374  END_KV_SERIALIZE_MAP()
375  };
376  typedef epee::misc_utils::struct_init<request_t> request;
377 
378  struct response_t
379  {
380  std::string version;
381  std::string os_version;
382  uint64_t connections_count;
383  uint64_t incoming_connections_count;
384  payload_stat_info payload_info;
385 
386  BEGIN_KV_SERIALIZE_MAP()
387  KV_SERIALIZE(version)
388  KV_SERIALIZE(os_version)
389  KV_SERIALIZE(connections_count)
390  KV_SERIALIZE(incoming_connections_count)
391  KV_SERIALIZE(payload_info)
392  END_KV_SERIALIZE_MAP()
393  };
394  typedef epee::misc_utils::struct_init<response_t> response;
395  };
396 
397 
398  /************************************************************************/
399  /* */
400  /************************************************************************/
401  struct COMMAND_REQUEST_NETWORK_STATE
402  {
403  const static int ID = P2P_COMMANDS_POOL_BASE + 5;
404 
405  struct request_t
406  {
407  proof_of_trust tr;
408  BEGIN_KV_SERIALIZE_MAP()
409  KV_SERIALIZE(tr)
410  END_KV_SERIALIZE_MAP()
411  };
412  typedef epee::misc_utils::struct_init<request_t> request;
413 
414  struct response_t
415  {
416  std::vector<peerlist_entry> local_peerlist_white;
417  std::vector<peerlist_entry> local_peerlist_gray;
418  std::vector<connection_entry> connections_list;
419  peerid_type my_id;
420  uint64_t local_time;
421  BEGIN_KV_SERIALIZE_MAP()
422  KV_SERIALIZE_CONTAINER_POD_AS_BLOB(local_peerlist_white)
423  KV_SERIALIZE_CONTAINER_POD_AS_BLOB(local_peerlist_gray)
424  KV_SERIALIZE_CONTAINER_POD_AS_BLOB(connections_list)
425  KV_SERIALIZE(my_id)
426  KV_SERIALIZE(local_time)
427  END_KV_SERIALIZE_MAP()
428  };
429  typedef epee::misc_utils::struct_init<response_t> response;
430  };
431 
432  /************************************************************************/
433  /* */
434  /************************************************************************/
435  struct COMMAND_REQUEST_PEER_ID
436  {
437  const static int ID = P2P_COMMANDS_POOL_BASE + 6;
438 
439  struct request_t
440  {
441  BEGIN_KV_SERIALIZE_MAP()
442  END_KV_SERIALIZE_MAP()
443  };
444  typedef epee::misc_utils::struct_init<request_t> request;
445 
446  struct response_t
447  {
448  peerid_type my_id;
449 
450  BEGIN_KV_SERIALIZE_MAP()
451  KV_SERIALIZE(my_id)
452  END_KV_SERIALIZE_MAP()
453  };
454  typedef epee::misc_utils::struct_init<response_t> response;
455  };
456 
457  /************************************************************************/
458  /* */
459  /************************************************************************/
460  struct COMMAND_REQUEST_SUPPORT_FLAGS
461  {
462  const static int ID = P2P_COMMANDS_POOL_BASE + 7;
463 
464  struct request_t
465  {
466  BEGIN_KV_SERIALIZE_MAP()
467  END_KV_SERIALIZE_MAP()
468  };
469  typedef epee::misc_utils::struct_init<request_t> request;
470 
471  struct response_t
472  {
473  uint32_t support_flags;
474 
475  BEGIN_KV_SERIALIZE_MAP()
476  KV_SERIALIZE(support_flags)
477  END_KV_SERIALIZE_MAP()
478  };
479  typedef epee::misc_utils::struct_init<response_t> response;
480  };
481 
482 #endif
483 
484 
485  inline crypto::hash get_proof_of_trust_hash(const nodetool::proof_of_trust& pot)
486  {
487  std::string s;
488  s.append(reinterpret_cast<const char*>(&pot.peer_id), sizeof(pot.peer_id));
489  s.append(reinterpret_cast<const char*>(&pot.time), sizeof(pot.time));
490  return crypto::cn_fast_hash(s.data(), s.size());
491  }
492 
493 }
#define s(x, c)
Definition: aesb.c:47
uint8_t version
Definition: blockchain.cpp:90
time_t time
Definition: blockchain.cpp:93
#define tr(x)
Definition: common_defines.h:4
void serialize(Archive &a, std::unordered_map< h_key, hval > &x, const boost::serialization::version_type ver)
Definition: unordered_containers_boost_serialization.h:127
void cn_fast_hash(const void *data, std::size_t length, hash &hash)
Definition: hash.h:69
POD_CLASS signature
Definition: crypto.h:108
POD_CLASS hash
Definition: hash.h:50
std::string hex(difficulty_type v)
Definition: difficulty.cpp:254
Definition: cryptonote_format_utils.h:44
Definition: net_node.cpp:110
boost::uuids::uuid uuid
Definition: net_node_common.h:43
static std::string peerid_to_string(peerid_type peer_id)
Definition: p2p_protocol_defs.h:53
uint64_t peerid_type
Definition: p2p_protocol_defs.h:51
std::string print_peerlist_to_string(const std::vector< peerlist_entry > &pl)
Definition: p2p_protocol_defs.h:126
crypto::hash get_proof_of_trust_hash(const nodetool::proof_of_trust &pot)
Definition: p2p_protocol_defs.h:485
peerlist_entry_base< epee::net_utils::network_address > peerlist_entry
Definition: p2p_protocol_defs.h:91
#define P2P_COMMANDS_POOL_BASE
Definition: p2p_protocol_defs.h:182
Definition: p2p_protocol_defs.h:193
t_playload_type payload_data
Definition: p2p_protocol_defs.h:195
basic_node_data node_data
Definition: p2p_protocol_defs.h:194
Definition: p2p_protocol_defs.h:205
basic_node_data node_data
Definition: p2p_protocol_defs.h:206
t_playload_type payload_data
Definition: p2p_protocol_defs.h:207
std::vector< peerlist_entry > local_peerlist_new
Definition: p2p_protocol_defs.h:208
Definition: p2p_protocol_defs.h:189
epee::misc_utils::struct_init< request_t > request
Definition: p2p_protocol_defs.h:202
epee::misc_utils::struct_init< response_t > response
Definition: p2p_protocol_defs.h:244
Definition: p2p_protocol_defs.h:324
Definition: p2p_protocol_defs.h:333
std::string status
Definition: p2p_protocol_defs.h:334
peerid_type peer_id
Definition: p2p_protocol_defs.h:335
Definition: p2p_protocol_defs.h:313
epee::misc_utils::struct_init< request_t > request
Definition: p2p_protocol_defs.h:330
epee::misc_utils::struct_init< response_t > response
Definition: p2p_protocol_defs.h:342
Definition: p2p_protocol_defs.h:257
t_playload_type payload_data
Definition: p2p_protocol_defs.h:258
Definition: p2p_protocol_defs.h:266
t_playload_type payload_data
Definition: p2p_protocol_defs.h:268
std::vector< peerlist_entry > local_peerlist_new
Definition: p2p_protocol_defs.h:269
uint64_t local_time
Definition: p2p_protocol_defs.h:267
Definition: p2p_protocol_defs.h:253
epee::misc_utils::struct_init< response_t > response
Definition: p2p_protocol_defs.h:305
epee::misc_utils::struct_init< request_t > request
Definition: p2p_protocol_defs.h:263
Definition: p2p_protocol_defs.h:95
int64_t first_seen
Definition: p2p_protocol_defs.h:98
AddressType adr
Definition: p2p_protocol_defs.h:96
peerid_type id
Definition: p2p_protocol_defs.h:97
Definition: p2p_protocol_defs.h:165
uint32_t my_port
Definition: p2p_protocol_defs.h:168
uint64_t local_time
Definition: p2p_protocol_defs.h:167
peerid_type peer_id
Definition: p2p_protocol_defs.h:170
uint16_t rpc_port
Definition: p2p_protocol_defs.h:169
uuid network_id
Definition: p2p_protocol_defs.h:166
Definition: p2p_protocol_defs.h:110
bool is_income
Definition: p2p_protocol_defs.h:113
AddressType adr
Definition: p2p_protocol_defs.h:111
peerid_type id
Definition: p2p_protocol_defs.h:112
Definition: p2p_protocol_defs.h:63
uint32_t port
Definition: p2p_protocol_defs.h:65
uint32_t ip
Definition: p2p_protocol_defs.h:64
Definition: p2p_protocol_defs.h:145
Definition: p2p_protocol_defs.h:75
uint32_t pruning_seed
Definition: p2p_protocol_defs.h:79
AddressType adr
Definition: p2p_protocol_defs.h:76
uint16_t rpc_port
Definition: p2p_protocol_defs.h:80
peerid_type id
Definition: p2p_protocol_defs.h:77
int64_t last_seen
Definition: p2p_protocol_defs.h:78