38 #include <boost/multi_index_container.hpp>
39 #include <boost/multi_index/ordered_index.hpp>
40 #include <boost/multi_index/identity.hpp>
41 #include <boost/multi_index/member.hpp>
42 #include <boost/optional/optional.hpp>
43 #include <boost/range/adaptor/reversed.hpp>
48 #include "net/enums.h"
49 #include "net/local_ip.h"
57 std::vector<peerlist_entry>
white;
58 std::vector<peerlist_entry>
gray;
59 std::vector<anchor_peerlist_entry>
anchor;
70 static boost::optional<peerlist_storage>
open(std::istream& src,
const bool new_format);
73 static boost::optional<peerlist_storage>
open(
const std::string& path);
105 bool merge_peerlist(
const std::vector<peerlist_entry>& outer_bs,
const std::function<
bool(
const peerlist_entry&)> &f = NULL);
107 void get_peerlist(std::vector<peerlist_entry>& pl_gray, std::vector<peerlist_entry>& pl_white);
111 template<
typename F>
bool foreach(
bool white,
const F &f);
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);
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);
163 typedef boost::multi_index_container<
165 boost::multi_index::indexed_by<
167 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 boost::multi_index::ordered_non_unique<boost::multi_index::tag<by_time>, boost::multi_index::member<peerlist_entry,int64_t,&peerlist_entry::last_seen> >
173 typedef boost::multi_index_container<
175 boost::multi_index::indexed_by<
177 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 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> >
184 void trim_white_peerlist();
185 void trim_gray_peerlist();
187 friend class boost::serialization::access;
202 peers_indexed::index<by_time>::type& sorted_index=m_peers_gray.get<
by_time>();
203 sorted_index.erase(sorted_index.begin());
211 peers_indexed::index<by_time>::type& sorted_index=m_peers_white.get<
by_time>();
212 sorted_index.erase(sorted_index.begin());
219 CRITICAL_REGION_LOCAL(m_peerlist_lock);
223 append_with_peer_gray(be);
226 trim_gray_peerlist();
233 CRITICAL_REGION_LOCAL(m_peerlist_lock);
234 if(i >= m_peers_white.size())
237 peers_indexed::index<by_time>::type& by_time_index = m_peers_white.get<
by_time>();
238 p = *epee::misc_utils::move_it_backward(--by_time_index.end(), i);
245 CRITICAL_REGION_LOCAL(m_peerlist_lock);
246 if(i >= m_peers_gray.size())
249 peers_indexed::index<by_time>::type& by_time_index = m_peers_gray.get<
by_time>();
250 p = *epee::misc_utils::move_it_backward(--by_time_index.end(), i);
258 if(address.is_loopback())
261 if(!m_allow_local_ip && address.is_local())
270 CRITICAL_REGION_LOCAL(m_peerlist_lock);
271 peers_indexed::index<by_time>::type& by_time_index=m_peers_white.get<
by_time>();
286 const uint32_t pick_depth = anonymize ? m_peers_white.size() :
depth;
287 bs_head.reserve(pick_depth);
288 for(
const peers_indexed::value_type& vl: boost::adaptors::reverse(by_time_index))
290 if(cnt++ >= pick_depth)
293 bs_head.push_back(vl);
299 if (bs_head.size() >
depth)
300 bs_head.resize(
depth);
301 for (
auto &e: bs_head)
308 template<
typename F>
inline
311 CRITICAL_REGION_LOCAL(m_peerlist_lock);
312 peers_indexed::index<by_time>::type& by_time_index = white ? m_peers_white.get<
by_time>() : m_peers_gray.get<
by_time>();
313 for(
const peers_indexed::value_type& vl: boost::adaptors::reverse(by_time_index))
323 CRITICAL_REGION_LOCAL(m_peerlist_lock);
332 return append_with_peer_white(ple);
333 CATCH_ENTRY_L0(
"peerlist_manager::set_peer_just_seen()",
false);
340 if(!is_host_allowed(ple.
adr))
343 CRITICAL_REGION_LOCAL(m_peerlist_lock);
345 auto by_addr_it_wt = m_peers_white.get<
by_addr>().find(ple.
adr);
346 if(by_addr_it_wt == m_peers_white.get<
by_addr>().end())
349 evict_host_from_white_peerlist(ple);
350 m_peers_white.insert(ple);
351 trim_white_peerlist();
356 if (by_addr_it_wt->pruning_seed && ple.
pruning_seed == 0)
358 if (by_addr_it_wt->rpc_port && ple.
rpc_port == 0)
359 new_ple.
rpc_port = by_addr_it_wt->rpc_port;
360 new_ple.
last_seen = by_addr_it_wt->last_seen;
361 m_peers_white.replace(by_addr_it_wt, new_ple);
364 auto by_addr_it_gr = m_peers_gray.get<
by_addr>().find(ple.
adr);
365 if(by_addr_it_gr != m_peers_gray.get<
by_addr>().end())
367 m_peers_gray.erase(by_addr_it_gr);
370 CATCH_ENTRY_L0(
"peerlist_manager::append_with_peer_white()",
false);
377 if(!is_host_allowed(ple.
adr))
380 CRITICAL_REGION_LOCAL(m_peerlist_lock);
382 auto by_addr_it_wt = m_peers_white.get<
by_addr>().find(ple.
adr);
383 if(by_addr_it_wt != m_peers_white.get<
by_addr>().end())
387 auto by_addr_it_gr = m_peers_gray.get<
by_addr>().find(ple.
adr);
388 if(by_addr_it_gr == m_peers_gray.get<
by_addr>().end())
391 m_peers_gray.insert(ple);
392 trim_gray_peerlist();
397 if (by_addr_it_gr->pruning_seed && ple.
pruning_seed == 0)
399 if (by_addr_it_gr->rpc_port && ple.
rpc_port == 0)
400 new_ple.
rpc_port = by_addr_it_gr->rpc_port;
401 new_ple.
last_seen = by_addr_it_gr->last_seen;
402 m_peers_gray.replace(by_addr_it_gr, new_ple);
405 CATCH_ENTRY_L0(
"peerlist_manager::append_with_peer_gray()",
false);
413 CRITICAL_REGION_LOCAL(m_peerlist_lock);
415 auto by_addr_it_anchor = m_peers_anchor.get<
by_addr>().find(ple.
adr);
417 if(by_addr_it_anchor == m_peers_anchor.get<
by_addr>().end()) {
418 m_peers_anchor.insert(ple);
423 CATCH_ENTRY_L0(
"peerlist_manager::append_with_peer_anchor()",
false);
431 CRITICAL_REGION_LOCAL(m_peerlist_lock);
433 if (m_peers_gray.empty()) {
439 peers_indexed::index<by_time>::type& by_time_index = m_peers_gray.get<
by_time>();
440 pe = *epee::misc_utils::move_it_backward(--by_time_index.end(), random_index);
444 CATCH_ENTRY_L0(
"peerlist_manager::get_random_gray_peer()",
false);
452 CRITICAL_REGION_LOCAL(m_peerlist_lock);
454 peers_indexed::index_iterator<by_addr>::type iterator = m_peers_white.get<
by_addr>().find(pe.
adr);
456 if (iterator != m_peers_white.get<
by_addr>().end()) {
457 m_peers_white.erase(iterator);
462 CATCH_ENTRY_L0(
"peerlist_manager::remove_from_peer_white()",
false);
470 CRITICAL_REGION_LOCAL(m_peerlist_lock);
472 peers_indexed::index_iterator<by_addr>::type iterator = m_peers_gray.get<
by_addr>().find(pe.
adr);
474 if (iterator != m_peers_gray.get<
by_addr>().end()) {
475 m_peers_gray.erase(iterator);
480 CATCH_ENTRY_L0(
"peerlist_manager::remove_from_peer_gray()",
false);
488 CRITICAL_REGION_LOCAL(m_peerlist_lock);
490 auto begin = m_peers_anchor.get<
by_time>().begin();
491 auto end = m_peers_anchor.get<
by_time>().end();
497 m_peers_anchor.get<
by_time>().clear();
501 CATCH_ENTRY_L0(
"peerlist_manager::get_and_empty_anchor_peerlist()",
false);
509 CRITICAL_REGION_LOCAL(m_peerlist_lock);
511 anchor_peers_indexed::index_iterator<by_addr>::type iterator = m_peers_anchor.get<
by_addr>().find(addr);
513 if (iterator != m_peers_anchor.get<
by_addr>().end()) {
514 m_peers_anchor.erase(iterator);
519 CATCH_ENTRY_L0(
"peerlist_manager::remove_from_peer_anchor()",
false);
static void init(std::string cache_filename)
Definition: blockchain_blackball.cpp:221
#define P2P_LOCAL_GRAY_PEERLIST_LIMIT
Definition: cryptonote_config.h:131
#define P2P_LOCAL_WHITE_PEERLIST_LIMIT
Definition: cryptonote_config.h:130
#define P2P_DEFAULT_PEERS_IN_HANDSHAKE
Definition: cryptonote_config.h:136
string a
Definition: MakeCryptoOps.py:15
const
Definition: build_protob.py:9
default
Definition: build_protob.py:9
std::enable_if< std::is_unsigned< T >::value, T >::type rand_idx(T sz)
Definition: crypto.h:191
Definition: cryptonote_format_utils.h:44
Definition: blockchain_ancestry.cpp:72
#define F(w, k)
Definition: sha512-blocks.c:61
CXA_THROW_INFO_T void(* dest)(void *))
Definition: stack_trace.cpp:90
Definition: p2p_protocol_defs.h:102
AddressType adr
Definition: p2p_protocol_defs.h:103
Definition: p2p_protocol_defs.h:72
uint32_t pruning_seed
Definition: p2p_protocol_defs.h:76
AddressType adr
Definition: p2p_protocol_defs.h:73
uint16_t rpc_port
Definition: p2p_protocol_defs.h:77
peerid_type id
Definition: p2p_protocol_defs.h:74
int64_t last_seen
Definition: p2p_protocol_defs.h:75
uint32_t rpc_credits_per_hash
Definition: p2p_protocol_defs.h:78
static __thread int depth
Definition: threadpool.cpp:34