Monero
Loading...
Searching...
No Matches
net_peerlist.h
Go to the documentation of this file.
1// Copyright (c) 2014-2022, The Monero Project
2//
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without modification, are
6// permitted provided that the following conditions are met:
7//
8// 1. Redistributions of source code must retain the above copyright notice, this list of
9// conditions and the following disclaimer.
10//
11// 2. Redistributions in binary form must reproduce the above copyright notice, this list
12// of conditions and the following disclaimer in the documentation and/or other
13// materials provided with the distribution.
14//
15// 3. Neither the name of the copyright holder nor the names of its contributors may be
16// used to endorse or promote products derived from this software without specific
17// prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
30
31#pragma once
32
33#include <iosfwd>
34#include <iterator>
35#include <list>
36#include <string>
37#include <vector>
38
39#include <boost/multi_index_container.hpp>
40#include <boost/multi_index/ordered_index.hpp>
41#include <boost/multi_index/identity.hpp>
42#include <boost/multi_index/member.hpp>
43#include <boost/optional/optional.hpp>
44#include <boost/range/adaptor/reversed.hpp>
45
46
47#include "crypto/crypto.h"
48#include "cryptonote_config.h"
49#include "net/enums.h"
50#include "p2p_protocol_defs.h"
51#include "syncobj.h"
52
53namespace nodetool
54{
56 {
57 std::vector<peerlist_entry> white;
58 std::vector<peerlist_entry> gray;
59 std::vector<anchor_peerlist_entry> anchor;
60 };
61
63 {
64 public:
66 : m_types{}
67 {}
68
70 static boost::optional<peerlist_storage> open(std::istream& src, const bool new_format);
71
73 static boost::optional<peerlist_storage> open(const std::string& path);
74
77
78 ~peerlist_storage() noexcept;
79
80 peerlist_storage& operator=(peerlist_storage&&) = default;
82
84 bool store(std::ostream& dest, const peerlist_types& other) const;
85
87 bool store(const std::string& path, const peerlist_types& other) const;
88
90 peerlist_types take_zone(epee::net_utils::zone zone);
91
92 private:
94 };
95
96 /************************************************************************/
97 /* */
98 /************************************************************************/
100 {
101 public:
102 bool init(peerlist_types&& peers, bool allow_local_ip);
105 bool merge_peerlist(const std::vector<peerlist_entry>& outer_bs, const std::function<bool(const peerlist_entry&)> &f = NULL);
106 bool get_peerlist_head(std::vector<peerlist_entry>& bs_head, bool anonymize, uint32_t depth = P2P_DEFAULT_PEERS_IN_HANDSHAKE);
107 void get_peerlist(std::vector<peerlist_entry>& pl_gray, std::vector<peerlist_entry>& pl_white);
108 void get_peerlist(peerlist_types& peers);
109 bool get_white_peer_by_index(peerlist_entry& p, size_t i);
110 bool get_gray_peer_by_index(peerlist_entry& p, size_t i);
111 template<typename F> bool foreach(bool white, const F &f);
112 void evict_host_from_peerlist(bool white, const peerlist_entry& pr);
113 bool append_with_peer_white(const peerlist_entry& pr, bool trust_last_seen = false);
114 bool append_with_peer_gray(const peerlist_entry& pr);
115 bool append_with_peer_anchor(const anchor_peerlist_entry& ple);
116 bool set_peer_just_seen(peerid_type peer, const epee::net_utils::network_address& addr, uint32_t pruning_seed, uint16_t rpc_port, uint32_t rpc_credits_per_hash);
117 bool is_host_allowed(const epee::net_utils::network_address &address);
118 bool get_random_gray_peer(peerlist_entry& pe);
119 bool remove_from_peer_gray(const peerlist_entry& pe);
120 bool get_and_empty_anchor_peerlist(std::vector<anchor_peerlist_entry>& apl);
121 bool remove_from_peer_anchor(const epee::net_utils::network_address& addr);
122 bool remove_from_peer_white(const peerlist_entry& pe);
123 template<typename F> size_t filter(bool white, const F &f); // f returns true: drop, false: keep
124
125 private:
126 struct by_time{};
127 struct by_id{};
128 struct by_addr{};
129
131 {
134 {
135 e.id = m_ple.id;
136 }
137 private:
139 };
140
142 {
143 modify_all(const peerlist_entry& ple):m_ple(ple){}
145 {
146 e = m_ple;
147 }
148 private:
150 };
151
153 {
154 modify_last_seen(time_t last_seen):m_last_seen(last_seen){}
156 {
157 e.last_seen = m_last_seen;
158 }
159 private:
161 };
162
163
164 typedef boost::multi_index_container<
166 boost::multi_index::indexed_by<
167 // access by peerlist_entry::net_adress
168 boost::multi_index::ordered_unique<boost::multi_index::tag<by_addr>, boost::multi_index::member<peerlist_entry,epee::net_utils::network_address,&peerlist_entry::adr> >,
169 // sort by peerlist_entry::last_seen<
170 boost::multi_index::ordered_non_unique<boost::multi_index::tag<by_time>, boost::multi_index::member<peerlist_entry,int64_t,&peerlist_entry::last_seen> >
171 >
173
174 typedef boost::multi_index_container<
176 boost::multi_index::indexed_by<
177 // access by anchor_peerlist_entry::net_adress
178 boost::multi_index::ordered_unique<boost::multi_index::tag<by_addr>, boost::multi_index::member<anchor_peerlist_entry,epee::net_utils::network_address,&anchor_peerlist_entry::adr> >,
179 // sort by anchor_peerlist_entry::first_seen
180 boost::multi_index::ordered_non_unique<boost::multi_index::tag<by_time>, boost::multi_index::member<anchor_peerlist_entry,int64_t,&anchor_peerlist_entry::first_seen> >
181 >
183
184 private:
185 void trim_white_peerlist();
186 void trim_gray_peerlist();
187 static peerlist_entry get_nth_latest_peer(peers_indexed& peerlist, size_t n);
188
189 friend class boost::serialization::access;
191 std::string m_config_folder;
193
194
198 };
199 //--------------------------------------------------------------------------------------------------
201 {
203 {
204 peers_indexed::index<by_time>::type& sorted_index=m_peers_gray.get<by_time>();
205 sorted_index.erase(sorted_index.begin());
206 }
207 }
208 //--------------------------------------------------------------------------------------------------
210 {
212 {
213 peers_indexed::index<by_time>::type& sorted_index=m_peers_white.get<by_time>();
214 sorted_index.erase(sorted_index.begin());
215 }
216 }
217 //--------------------------------------------------------------------------------------------------
218 inline
220 {
221 // Is not thread-safe nor does it check bounds. Do this before calling. Indexing starts at 0.
222 peers_indexed::index<by_time>::type& by_time_index = peerlist.get<by_time>();
223 auto by_time_it = --by_time_index.end();
224 std::advance(by_time_it, -static_cast<long long>(n));
225 return *by_time_it;
226 }
227 //--------------------------------------------------------------------------------------------------
228 inline
229 bool peerlist_manager::merge_peerlist(const std::vector<peerlist_entry>& outer_bs, const std::function<bool(const peerlist_entry&)> &f)
230 {
232 for(const peerlist_entry& be: outer_bs)
233 {
234 if (!f || f(be))
236 }
237 // delete extra elements
239 return true;
240 }
241 //--------------------------------------------------------------------------------------------------
242 inline
244 {
246 if(i >= m_peers_white.size())
247 return false;
248
250 return true;
251 }
252 //--------------------------------------------------------------------------------------------------
253 inline
255 {
257 if(i >= m_peers_gray.size())
258 return false;
259
261 return true;
262 }
263 //--------------------------------------------------------------------------------------------------
264 inline
266 {
267 //never allow loopback ip
268 if(address.is_loopback())
269 return false;
270
271 if(!m_allow_local_ip && address.is_local())
272 return false;
273
274 return true;
275 }
276 //--------------------------------------------------------------------------------------------------
277 inline
278 bool peerlist_manager::get_peerlist_head(std::vector<peerlist_entry>& bs_head, bool anonymize, uint32_t depth)
279 {
281 peers_indexed::index<by_time>::type& by_time_index=m_peers_white.get<by_time>();
282 uint32_t cnt = 0;
283
284 // picks a random set of peers within the whole set, rather pick the first depth elements.
285 // The intent is that if someone asks twice, they can't easily tell:
286 // - this address was not in the first list, but is in the second, so the only way this can be
287 // is if its last_seen was recently reset, so this means the target node recently had a new
288 // connection to that address
289 // - this address was in the first list, and not in the second, which means either the address
290 // was moved to the gray list (if it's not accessible, which the attacker can check if
291 // the address accepts incoming connections) or it was the oldest to still fit in the 250 items,
292 // so its last_seen is old.
293 //
294 // See Cao, Tong et al. "Exploring the Monero Peer-to-Peer Network". https://eprint.iacr.org/2019/411
295 //
296 const uint32_t pick_depth = anonymize ? m_peers_white.size() : depth;
297 bs_head.reserve(pick_depth);
298 for(const peers_indexed::value_type& vl: boost::adaptors::reverse(by_time_index))
299 {
300 if(cnt++ >= pick_depth)
301 break;
302
303 bs_head.push_back(vl);
304 }
305
306 if (anonymize)
307 {
308 std::shuffle(bs_head.begin(), bs_head.end(), crypto::random_device{});
309 if (bs_head.size() > depth)
310 bs_head.resize(depth);
311 for (auto &e: bs_head)
312 e.last_seen = 0;
313 }
314
315 return true;
316 }
317 //--------------------------------------------------------------------------------------------------
318 template<typename F> inline
319 bool peerlist_manager::foreach(bool white, const F &f)
320 {
322 peers_indexed::index<by_time>::type& by_time_index = white ? m_peers_white.get<by_time>() : m_peers_gray.get<by_time>();
323 for(const peers_indexed::value_type& vl: boost::adaptors::reverse(by_time_index))
324 if (!f(vl))
325 return false;
326 return true;
327 }
328 //--------------------------------------------------------------------------------------------------
329 inline
330 bool peerlist_manager::set_peer_just_seen(peerid_type peer, const epee::net_utils::network_address& addr, uint32_t pruning_seed, uint16_t rpc_port, uint32_t rpc_credits_per_hash)
331 {
332 TRY_ENTRY();
334 //find in white list
335 peerlist_entry ple;
336 ple.adr = addr;
337 ple.id = peer;
338 ple.last_seen = time(NULL);
339 ple.pruning_seed = pruning_seed;
340 ple.rpc_port = rpc_port;
341 ple.rpc_credits_per_hash = rpc_credits_per_hash;
342 return append_with_peer_white(ple, true);
343 CATCH_ENTRY_L0("peerlist_manager::set_peer_just_seen()", false);
344 }
345 //--------------------------------------------------------------------------------------------------
346 inline
347 bool peerlist_manager::append_with_peer_white(const peerlist_entry& ple, bool trust_last_seen)
348 {
349 TRY_ENTRY();
350 if(!is_host_allowed(ple.adr))
351 return true;
352
354 //find in white list
355 auto by_addr_it_wt = m_peers_white.get<by_addr>().find(ple.adr);
356 if(by_addr_it_wt == m_peers_white.get<by_addr>().end())
357 {
358 //put new record into white list
359 evict_host_from_peerlist(true, ple);
360 m_peers_white.insert(ple);
362 }else
363 {
364 //update record in white list
365 peerlist_entry new_ple = ple;
366 if (by_addr_it_wt->pruning_seed && ple.pruning_seed == 0) // guard against older nodes not passing pruning info around
367 new_ple.pruning_seed = by_addr_it_wt->pruning_seed;
368 if (by_addr_it_wt->rpc_port && ple.rpc_port == 0) // guard against older nodes not passing RPC port around
369 new_ple.rpc_port = by_addr_it_wt->rpc_port;
370 if (!trust_last_seen)
371 new_ple.last_seen = by_addr_it_wt->last_seen; // do not overwrite the last seen timestamp, incoming peer lists are untrusted
372 m_peers_white.replace(by_addr_it_wt, new_ple);
373 }
374 //remove from gray list, if need
375 auto by_addr_it_gr = m_peers_gray.get<by_addr>().find(ple.adr);
376 if(by_addr_it_gr != m_peers_gray.get<by_addr>().end())
377 {
378 m_peers_gray.erase(by_addr_it_gr);
379 }
380 return true;
381 CATCH_ENTRY_L0("peerlist_manager::append_with_peer_white()", false);
382 }
383 //--------------------------------------------------------------------------------------------------
384 inline
386 {
387 TRY_ENTRY();
388 if(!is_host_allowed(ple.adr))
389 return true;
390
392 //find in white list
393 auto by_addr_it_wt = m_peers_white.get<by_addr>().find(ple.adr);
394 if(by_addr_it_wt != m_peers_white.get<by_addr>().end())
395 return true;
396
397 //update gray list
398 auto by_addr_it_gr = m_peers_gray.get<by_addr>().find(ple.adr);
399 if(by_addr_it_gr == m_peers_gray.get<by_addr>().end())
400 {
401 //put new record into white list
402 m_peers_gray.insert(ple);
404 }else
405 {
406 //update record in gray list
407 peerlist_entry new_ple = ple;
408 if (by_addr_it_gr->pruning_seed && ple.pruning_seed == 0) // guard against older nodes not passing pruning info around
409 new_ple.pruning_seed = by_addr_it_gr->pruning_seed;
410 if (by_addr_it_gr->rpc_port && ple.rpc_port == 0) // guard against older nodes not passing RPC port around
411 new_ple.rpc_port = by_addr_it_gr->rpc_port;
412 new_ple.last_seen = by_addr_it_gr->last_seen; // do not overwrite the last seen timestamp, incoming peer list are untrusted
413 m_peers_gray.replace(by_addr_it_gr, new_ple);
414 }
415 return true;
416 CATCH_ENTRY_L0("peerlist_manager::append_with_peer_gray()", false);
417 }
418 //--------------------------------------------------------------------------------------------------
419 inline
421 {
422 TRY_ENTRY();
423
425
426 auto by_addr_it_anchor = m_peers_anchor.get<by_addr>().find(ple.adr);
427
428 if(by_addr_it_anchor == m_peers_anchor.get<by_addr>().end()) {
429 m_peers_anchor.insert(ple);
430 }
431
432 return true;
433
434 CATCH_ENTRY_L0("peerlist_manager::append_with_peer_anchor()", false);
435 }
436 //--------------------------------------------------------------------------------------------------
437 inline
439 {
440 TRY_ENTRY();
441
443
444 if (m_peers_gray.empty()) {
445 return false;
446 }
447
448 size_t random_index = crypto::rand_idx(m_peers_gray.size());
450
451 return true;
452
453 CATCH_ENTRY_L0("peerlist_manager::get_random_gray_peer()", false);
454 }
455 //--------------------------------------------------------------------------------------------------
456 inline
458 {
459 TRY_ENTRY();
460
462
463 peers_indexed::index_iterator<by_addr>::type iterator = m_peers_white.get<by_addr>().find(pe.adr);
464
465 if (iterator != m_peers_white.get<by_addr>().end()) {
466 m_peers_white.erase(iterator);
467 }
468
469 return true;
470
471 CATCH_ENTRY_L0("peerlist_manager::remove_from_peer_white()", false);
472 }
473 //--------------------------------------------------------------------------------------------------
474 inline
476 {
477 TRY_ENTRY();
478
480
481 peers_indexed::index_iterator<by_addr>::type iterator = m_peers_gray.get<by_addr>().find(pe.adr);
482
483 if (iterator != m_peers_gray.get<by_addr>().end()) {
484 m_peers_gray.erase(iterator);
485 }
486
487 return true;
488
489 CATCH_ENTRY_L0("peerlist_manager::remove_from_peer_gray()", false);
490 }
491 //--------------------------------------------------------------------------------------------------
492 inline
493 bool peerlist_manager::get_and_empty_anchor_peerlist(std::vector<anchor_peerlist_entry>& apl)
494 {
495 TRY_ENTRY();
496
498
499 auto begin = m_peers_anchor.get<by_time>().begin();
500 auto end = m_peers_anchor.get<by_time>().end();
501
502 std::for_each(begin, end, [&apl](const anchor_peerlist_entry &a) {
503 apl.push_back(a);
504 });
505
506 m_peers_anchor.get<by_time>().clear();
507
508 return true;
509
510 CATCH_ENTRY_L0("peerlist_manager::get_and_empty_anchor_peerlist()", false);
511 }
512 //--------------------------------------------------------------------------------------------------
513 inline
515 {
516 TRY_ENTRY();
517
519
520 anchor_peers_indexed::index_iterator<by_addr>::type iterator = m_peers_anchor.get<by_addr>().find(addr);
521
522 if (iterator != m_peers_anchor.get<by_addr>().end()) {
523 m_peers_anchor.erase(iterator);
524 }
525
526 return true;
527
528 CATCH_ENTRY_L0("peerlist_manager::remove_from_peer_anchor()", false);
529 }
530 //--------------------------------------------------------------------------------------------------
531 template<typename F> size_t peerlist_manager::filter(bool white, const F &f)
532 {
533 size_t filtered = 0;
534 TRY_ENTRY();
536 peers_indexed::index<by_addr>::type& sorted_index = white ? m_peers_white.get<by_addr>() : m_peers_gray.get<by_addr>();
537 auto i = sorted_index.begin();
538 while (i != sorted_index.end())
539 {
540 if (f(*i))
541 {
542 i = sorted_index.erase(i);
543 ++filtered;
544 }
545 else
546 ++i;
547 }
548 CATCH_ENTRY_L0("peerlist_manager::filter()", filtered);
549 return filtered;
550 }
551 //--------------------------------------------------------------------------------------------------
552}
553
Definition syncobj.h:82
Definition net_utils_base.h:225
Definition net_peerlist.h:100
bool get_gray_peer_by_index(peerlist_entry &p, size_t i)
Definition net_peerlist.h:254
bool foreach(bool white, const F &f)
Definition net_peerlist.h:319
std::string m_config_folder
Definition net_peerlist.h:191
bool append_with_peer_anchor(const anchor_peerlist_entry &ple)
Definition net_peerlist.h:420
boost::multi_index_container< peerlist_entry, boost::multi_index::indexed_by< boost::multi_index::ordered_unique< boost::multi_index::tag< by_addr >, boost::multi_index::member< peerlist_entry, epee::net_utils::network_address,&peerlist_entry::adr > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< by_time >, boost::multi_index::member< peerlist_entry, int64_t,&peerlist_entry::last_seen > > > > peers_indexed
Definition net_peerlist.h:172
bool set_peer_just_seen(peerid_type peer, const epee::net_utils::network_address &addr, uint32_t pruning_seed, uint16_t rpc_port, uint32_t rpc_credits_per_hash)
Definition net_peerlist.h:330
bool merge_peerlist(const std::vector< peerlist_entry > &outer_bs, const std::function< bool(const peerlist_entry &)> &f=NULL)
Definition net_peerlist.h:229
bool get_and_empty_anchor_peerlist(std::vector< anchor_peerlist_entry > &apl)
Definition net_peerlist.h:493
bool get_random_gray_peer(peerlist_entry &pe)
Definition net_peerlist.h:438
bool remove_from_peer_white(const peerlist_entry &pe)
Definition net_peerlist.h:457
bool m_allow_local_ip
Definition net_peerlist.h:192
void trim_gray_peerlist()
Definition net_peerlist.h:200
bool append_with_peer_gray(const peerlist_entry &pr)
Definition net_peerlist.h:385
boost::multi_index_container< anchor_peerlist_entry, boost::multi_index::indexed_by< boost::multi_index::ordered_unique< boost::multi_index::tag< by_addr >, boost::multi_index::member< anchor_peerlist_entry, epee::net_utils::network_address,&anchor_peerlist_entry::adr > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< by_time >, boost::multi_index::member< anchor_peerlist_entry, int64_t,&anchor_peerlist_entry::first_seen > > > > anchor_peers_indexed
Definition net_peerlist.h:182
static peerlist_entry get_nth_latest_peer(peers_indexed &peerlist, size_t n)
Definition net_peerlist.h:219
epee::critical_section m_peerlist_lock
Definition net_peerlist.h:190
void trim_white_peerlist()
Definition net_peerlist.h:209
bool append_with_peer_white(const peerlist_entry &pr, bool trust_last_seen=false)
Definition net_peerlist.h:347
size_t get_gray_peers_count()
Definition net_peerlist.h:104
bool remove_from_peer_gray(const peerlist_entry &pe)
Definition net_peerlist.h:475
bool remove_from_peer_anchor(const epee::net_utils::network_address &addr)
Definition net_peerlist.h:514
bool get_peerlist_head(std::vector< peerlist_entry > &bs_head, bool anonymize, uint32_t depth=P2P_DEFAULT_PEERS_IN_HANDSHAKE)
Definition net_peerlist.h:278
peers_indexed m_peers_white
Definition net_peerlist.h:196
anchor_peers_indexed m_peers_anchor
Definition net_peerlist.h:197
bool get_white_peer_by_index(peerlist_entry &p, size_t i)
Definition net_peerlist.h:243
peers_indexed m_peers_gray
Definition net_peerlist.h:195
size_t filter(bool white, const F &f)
Definition net_peerlist.h:531
size_t get_white_peers_count()
Definition net_peerlist.h:103
bool is_host_allowed(const epee::net_utils::network_address &address)
Definition net_peerlist.h:265
void evict_host_from_peerlist(bool white, const peerlist_entry &pr)
Definition net_peerlist.cpp:294
static boost::optional< peerlist_storage > open(std::istream &src, const bool new_format)
Definition net_peerlist.cpp:163
peerlist_types m_types
Definition net_peerlist.h:93
peerlist_storage(peerlist_storage &&)=default
bool store(std::ostream &dest, const peerlist_types &other) const
Save peers from this and other in stream dest.
Definition net_peerlist.cpp:227
peerlist_storage(const peerlist_storage &)=delete
peerlist_types take_zone(epee::net_utils::zone zone)
Definition net_peerlist.cpp:252
~peerlist_storage() noexcept
Definition net_peerlist.cpp:224
peerlist_storage()
Definition net_peerlist.h:65
#define P2P_LOCAL_GRAY_PEERLIST_LIMIT
Definition cryptonote_config.h:137
#define P2P_LOCAL_WHITE_PEERLIST_LIMIT
Definition cryptonote_config.h:136
#define P2P_DEFAULT_PEERS_IN_HANDSHAKE
Definition cryptonote_config.h:142
#define const
Definition ipfrdr.c:80
static void init()
Definition logging.cpp:42
uint32_t address
Definition getifaddr.c:269
std::enable_if< std::is_unsigned< T >::value, T >::type rand_idx(T sz)
Definition crypto.h:204
TODO: (mj-xmr) This will be reduced in an another PR.
Definition byte_slice.h:40
Definition levin_notify.h:52
uint64_t peerid_type
Definition p2p_protocol_defs.h:49
anchor_peerlist_entry_base< epee::net_utils::network_address > anchor_peerlist_entry
Definition p2p_protocol_defs.h:120
peerlist_entry_base< epee::net_utils::network_address > peerlist_entry
Definition p2p_protocol_defs.h:99
Definition enums.h:68
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1124
#define F(w, k)
Definition sha512-blocks.c:61
static __thread int depth
Definition threadpool.cpp:34
CXA_THROW_INFO_T void(* dest)(void *))
Definition stack_trace.cpp:91
unsigned short uint16_t
Definition stdint.h:125
unsigned int uint32_t
Definition stdint.h:126
Definition crypto.h:185
AddressType adr
Definition p2p_protocol_defs.h:104
uint32_t pruning_seed
Definition p2p_protocol_defs.h:77
AddressType adr
Definition p2p_protocol_defs.h:74
uint16_t rpc_port
Definition p2p_protocol_defs.h:78
peerid_type id
Definition p2p_protocol_defs.h:75
int64_t last_seen
Definition p2p_protocol_defs.h:76
uint32_t rpc_credits_per_hash
Definition p2p_protocol_defs.h:79
Definition net_peerlist.h:128
Definition net_peerlist.h:127
Definition net_peerlist.h:126
modify_all_but_id(const peerlist_entry &ple)
Definition net_peerlist.h:132
void operator()(peerlist_entry &e)
Definition net_peerlist.h:133
const peerlist_entry & m_ple
Definition net_peerlist.h:138
modify_all(const peerlist_entry &ple)
Definition net_peerlist.h:143
void operator()(peerlist_entry &e)
Definition net_peerlist.h:144
const peerlist_entry & m_ple
Definition net_peerlist.h:149
modify_last_seen(time_t last_seen)
Definition net_peerlist.h:154
time_t m_last_seen
Definition net_peerlist.h:160
void operator()(peerlist_entry &e)
Definition net_peerlist.h:155
Definition net_peerlist.h:56
std::vector< anchor_peerlist_entry > anchor
Definition net_peerlist.h:59
std::vector< peerlist_entry > gray
Definition net_peerlist.h:58
std::vector< peerlist_entry > white
Definition net_peerlist.h:57
#define CRITICAL_REGION_LOCAL(x)
Definition syncobj.h:153