aboutsummaryrefslogtreecommitdiff
path: root/src/p2p
diff options
context:
space:
mode:
Diffstat (limited to 'src/p2p')
-rw-r--r--src/p2p/net_node.h15
-rw-r--r--src/p2p/net_node.inl198
-rw-r--r--src/p2p/net_node_common.h12
-rw-r--r--src/p2p/net_peerlist.h36
-rw-r--r--src/p2p/net_peerlist_boost_serialization.h17
-rw-r--r--src/p2p/p2p_protocol_defs.h10
6 files changed, 234 insertions, 54 deletions
diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h
index 0ef2dbb30..09c219a44 100644
--- a/src/p2p/net_node.h
+++ b/src/p2p/net_node.h
@@ -29,6 +29,7 @@
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
#pragma once
+#include <array>
#include <boost/thread.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/variables_map.hpp>
@@ -127,6 +128,11 @@ namespace nodetool
virtual bool block_host(const epee::net_utils::network_address &adress, time_t seconds = P2P_IP_BLOCKTIME);
virtual bool unblock_host(const epee::net_utils::network_address &address);
virtual std::map<std::string, time_t> get_blocked_hosts() { CRITICAL_REGION_LOCAL(m_blocked_hosts_lock); return m_blocked_hosts; }
+
+ virtual void add_used_stripe_peer(const typename t_payload_net_handler::connection_context &context);
+ virtual void remove_used_stripe_peer(const typename t_payload_net_handler::connection_context &context);
+ virtual void clear_used_stripe_peers();
+
private:
const std::vector<std::string> m_seed_nodes_list =
{ "seeds.moneroseeds.se"
@@ -235,7 +241,13 @@ namespace nodetool
bool parse_peers_and_add_to_container(const boost::program_options::variables_map& vm, const command_line::arg_descriptor<std::vector<std::string> > & arg, Container& container);
bool set_max_out_peers(const boost::program_options::variables_map& vm, int64_t max);
+ bool get_max_out_peers() const { return m_config.m_net_config.max_out_connection_count; }
+ bool get_current_out_peers() const { return m_current_number_of_out_peers; }
+
bool set_max_in_peers(const boost::program_options::variables_map& vm, int64_t max);
+ bool get_max_in_peers() const { return m_config.m_net_config.max_in_connection_count; }
+ bool get_current_in_peers() const { return m_current_number_of_in_peers; }
+
bool set_tos_flag(const boost::program_options::variables_map& vm, int limit);
bool set_rate_up_limit(const boost::program_options::variables_map& vm, int64_t limit);
@@ -336,6 +348,9 @@ namespace nodetool
epee::critical_section m_host_fails_score_lock;
std::map<std::string, uint64_t> m_host_fails_score;
+ boost::mutex m_used_stripe_peers_mutex;
+ std::array<std::list<epee::net_utils::network_address>, 1 << CRYPTONOTE_PRUNING_LOG_STRIPES> m_used_stripe_peers;
+
cryptonote::network_type m_nettype;
};
diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl
index 25ac1ba18..c594984d4 100644
--- a/src/p2p/net_node.inl
+++ b/src/p2p/net_node.inl
@@ -41,6 +41,7 @@
#include "string_tools.h"
#include "common/util.h"
#include "common/dns_utils.h"
+#include "common/pruning.h"
#include "net/net_helper.h"
#include "math_helper.h"
#include "p2p_protocol_defs.h"
@@ -133,6 +134,28 @@ namespace nodetool
make_default_config();
}
+#ifdef CRYPTONOTE_PRUNING_DEBUG_SPOOF_SEED
+ std::list<peerlist_entry> plw;
+ while (m_peerlist.get_white_peers_count())
+ {
+ plw.push_back(peerlist_entry());
+ m_peerlist.get_white_peer_by_index(plw.back(), 0);
+ m_peerlist.remove_from_peer_white(plw.back());
+ }
+ for (auto &e:plw)
+ m_peerlist.append_with_peer_white(e);
+
+ std::list<peerlist_entry> plg;
+ while (m_peerlist.get_gray_peers_count())
+ {
+ plg.push_back(peerlist_entry());
+ m_peerlist.get_gray_peer_by_index(plg.back(), 0);
+ m_peerlist.remove_from_peer_gray(plg.back());
+ }
+ for (auto &e:plg)
+ m_peerlist.append_with_peer_gray(e);
+#endif
+
// always recreate a new peer id
make_default_peer_id();
@@ -729,7 +752,7 @@ namespace nodetool
std::atomic<bool> hsh_result(false);
bool r = epee::net_utils::async_invoke_remote_command2<typename COMMAND_HANDSHAKE::response>(context_.m_connection_id, COMMAND_HANDSHAKE::ID, arg, m_net_server.get_config_object(),
- [this, &pi, &ev, &hsh_result, &just_take_peerlist](int code, const typename COMMAND_HANDSHAKE::response& rsp, p2p_connection_context& context)
+ [this, &pi, &ev, &hsh_result, &just_take_peerlist, &context_](int code, const typename COMMAND_HANDSHAKE::response& rsp, p2p_connection_context& context)
{
epee::misc_utils::auto_scope_leave_caller scope_exit_handler = epee::misc_utils::create_scope_leave_handler([&](){ev.raise();});
@@ -762,7 +785,7 @@ namespace nodetool
}
pi = context.peer_id = rsp.node_data.peer_id;
- m_peerlist.set_peer_just_seen(rsp.node_data.peer_id, context.m_remote_address);
+ m_peerlist.set_peer_just_seen(rsp.node_data.peer_id, context.m_remote_address, context.m_pruning_seed);
if(rsp.node_data.peer_id == m_config.m_peer_id)
{
@@ -770,11 +793,13 @@ namespace nodetool
hsh_result = false;
return;
}
+ LOG_INFO_CC(context, "New connection handshaked, pruning seed " << epee::string_tools::to_string_hex(context.m_pruning_seed));
LOG_DEBUG_CC(context, " COMMAND_HANDSHAKE INVOKED OK");
}else
{
LOG_DEBUG_CC(context, " COMMAND_HANDSHAKE(AND CLOSE) INVOKED OK");
}
+ context_ = context;
}, P2P_DEFAULT_HANDSHAKE_INVOKE_TIMEOUT);
if(r)
@@ -821,7 +846,7 @@ namespace nodetool
add_host_fail(context.m_remote_address);
}
if(!context.m_is_income)
- m_peerlist.set_peer_just_seen(context.peer_id, context.m_remote_address);
+ m_peerlist.set_peer_just_seen(context.peer_id, context.m_remote_address, context.m_pruning_seed);
m_payload_handler.process_payload_sync_data(rsp.payload_data, context, false);
});
@@ -939,6 +964,7 @@ namespace nodetool
const epee::net_utils::ipv4_network_address &ipv4 = na.as<const epee::net_utils::ipv4_network_address>();
typename net_server::t_connection_context con = AUTO_VAL_INIT(con);
+ con.m_anchor = peer_type == anchor;
bool res = m_net_server.connect(epee::string_tools::get_ip_string_from_int32(ipv4.ip()),
epee::string_tools::num_to_string_fast(ipv4.port()),
m_config.m_net_config.connection_timeout,
@@ -978,6 +1004,7 @@ namespace nodetool
time_t last_seen;
time(&last_seen);
pe_local.last_seen = static_cast<int64_t>(last_seen);
+ pe_local.pruning_seed = con.m_pruning_seed;
m_peerlist.append_with_peer_white(pe_local);
//update last seen and push it to peerlist manager
@@ -1004,6 +1031,7 @@ namespace nodetool
const epee::net_utils::ipv4_network_address &ipv4 = na.as<epee::net_utils::ipv4_network_address>();
typename net_server::t_connection_context con = AUTO_VAL_INIT(con);
+ con.m_anchor = false;
bool res = m_net_server.connect(epee::string_tools::get_ip_string_from_int32(ipv4.ip()),
epee::string_tools::num_to_string_fast(ipv4.port()),
m_config.m_net_config.connection_timeout,
@@ -1056,7 +1084,7 @@ namespace nodetool
bool node_server<t_payload_net_handler>::make_new_connection_from_anchor_peerlist(const std::vector<anchor_peerlist_entry>& anchor_peerlist)
{
for (const auto& pe: anchor_peerlist) {
- _note("Considering connecting (out) to peer: " << peerid_type(pe.id) << " " << pe.adr.str());
+ _note("Considering connecting (out) to anchor peer: " << peerid_type(pe.id) << " " << pe.adr.str());
if(is_peer_used(pe)) {
_note("Peer is used");
@@ -1089,11 +1117,7 @@ namespace nodetool
template<class t_payload_net_handler>
bool node_server<t_payload_net_handler>::make_new_connection_from_peerlist(bool use_white_list)
{
- size_t local_peers_count = use_white_list ? m_peerlist.get_white_peers_count():m_peerlist.get_gray_peers_count();
- if(!local_peers_count)
- return false;//no peers
-
- size_t max_random_index = std::min<uint64_t>(local_peers_count -1, 20);
+ size_t max_random_index = 0;
std::set<size_t> tried_peers;
@@ -1103,21 +1127,54 @@ namespace nodetool
{
++rand_count;
size_t random_index;
+ const uint32_t next_needed_pruning_stripe = m_payload_handler.get_next_needed_pruning_stripe().second;
- if (use_white_list) {
- local_peers_count = m_peerlist.get_white_peers_count();
- if (!local_peers_count)
+ std::deque<size_t> filtered;
+ const size_t limit = use_white_list ? 20 : std::numeric_limits<size_t>::max();
+ size_t idx = 0;
+ m_peerlist.foreach (use_white_list, [&filtered, &idx, limit, next_needed_pruning_stripe](const peerlist_entry &pe){
+ if (filtered.size() >= limit)
return false;
- max_random_index = std::min<uint64_t>(local_peers_count -1, 20);
- random_index = get_random_index_with_fixed_probability(max_random_index);
- } else {
- local_peers_count = m_peerlist.get_gray_peers_count();
- if (!local_peers_count)
- return false;
- random_index = crypto::rand<size_t>() % local_peers_count;
+ if (next_needed_pruning_stripe == 0 || pe.pruning_seed == 0)
+ filtered.push_back(idx);
+ else if (next_needed_pruning_stripe == tools::get_pruning_stripe(pe.pruning_seed))
+ filtered.push_front(idx);
+ ++idx;
+ return true;
+ });
+ if (filtered.empty())
+ {
+ MDEBUG("No available peer in " << (use_white_list ? "white" : "gray") << " list filtered by " << next_needed_pruning_stripe);
+ return false;
}
+ if (use_white_list)
+ {
+ // if using the white list, we first pick in the set of peers we've already been using earlier
+ random_index = get_random_index_with_fixed_probability(std::min<uint64_t>(filtered.size() - 1, 20));
+ CRITICAL_REGION_LOCAL(m_used_stripe_peers_mutex);
+ if (next_needed_pruning_stripe > 0 && next_needed_pruning_stripe <= (1ul << CRYPTONOTE_PRUNING_LOG_STRIPES) && !m_used_stripe_peers[next_needed_pruning_stripe-1].empty())
+ {
+ const epee::net_utils::network_address na = m_used_stripe_peers[next_needed_pruning_stripe-1].front();
+ m_used_stripe_peers[next_needed_pruning_stripe-1].pop_front();
+ for (size_t i = 0; i < filtered.size(); ++i)
+ {
+ peerlist_entry pe;
+ if (m_peerlist.get_white_peer_by_index(pe, filtered[i]) && pe.adr == na)
+ {
+ MDEBUG("Reusing stripe " << next_needed_pruning_stripe << " peer " << pe.adr.str());
+ random_index = i;
+ break;
+ }
+ }
+ }
+ }
+ else
+ random_index = crypto::rand<size_t>() % filtered.size();
- CHECK_AND_ASSERT_MES(random_index < local_peers_count, false, "random_starter_index < peers_local.size() failed!!");
+ CHECK_AND_ASSERT_MES(random_index < filtered.size(), false, "random_index < filtered.size() failed!!");
+ random_index = filtered[random_index];
+ CHECK_AND_ASSERT_MES(random_index < (use_white_list ? m_peerlist.get_white_peers_count() : m_peerlist.get_gray_peers_count()),
+ false, "random_index < peers size failed!!");
if(tried_peers.count(random_index))
continue;
@@ -1129,7 +1186,9 @@ namespace nodetool
++try_count;
- _note("Considering connecting (out) to peer: " << peerid_to_string(pe.id) << " " << pe.adr.str());
+ _note("Considering connecting (out) to " << (use_white_list ? "white" : "gray") << " list peer: " <<
+ peerid_to_string(pe.id) << " " << pe.adr.str() << ", pruning seed " << epee::string_tools::to_string_hex(pe.pruning_seed) <<
+ " (stripe " << next_needed_pruning_stripe << " needed)");
if(is_peer_used(pe)) {
_note("Peer is used");
@@ -1143,6 +1202,7 @@ namespace nodetool
continue;
MDEBUG("Selected peer: " << peerid_to_string(pe.id) << " " << pe.adr.str()
+ << ", pruning seed " << epee::string_tools::to_string_hex(pe.pruning_seed) << " "
<< "[peer_list=" << (use_white_list ? white : gray)
<< "] last_seen: " << (pe.last_seen ? epee::misc_utils::get_time_interval_string(time(NULL) - pe.last_seen) : "never"));
@@ -1219,31 +1279,35 @@ namespace nodetool
if (!connect_to_peerlist(m_priority_peers)) return false;
- size_t expected_white_connections = (m_config.m_net_config.max_out_connection_count*P2P_DEFAULT_WHITELIST_CONNECTIONS_PERCENT)/100;
+ size_t base_expected_white_connections = (m_config.m_net_config.max_out_connection_count*P2P_DEFAULT_WHITELIST_CONNECTIONS_PERCENT)/100;
size_t conn_count = get_outgoing_connections_count();
- if(conn_count < m_config.m_net_config.max_out_connection_count)
+ while(conn_count < m_config.m_net_config.max_out_connection_count)
{
+ const size_t expected_white_connections = m_payload_handler.get_next_needed_pruning_stripe().second ? m_config.m_net_config.max_out_connection_count : base_expected_white_connections;
if(conn_count < expected_white_connections)
{
//start from anchor list
- if(!make_expected_connections_count(anchor, P2P_DEFAULT_ANCHOR_CONNECTIONS_COUNT))
- return false;
+ while (get_outgoing_connections_count() < P2P_DEFAULT_ANCHOR_CONNECTIONS_COUNT
+ && make_expected_connections_count(anchor, P2P_DEFAULT_ANCHOR_CONNECTIONS_COUNT));
//then do white list
- if(!make_expected_connections_count(white, expected_white_connections))
- return false;
+ while (get_outgoing_connections_count() < expected_white_connections
+ && make_expected_connections_count(white, expected_white_connections));
//then do grey list
- if(!make_expected_connections_count(gray, m_config.m_net_config.max_out_connection_count))
- return false;
+ while (get_outgoing_connections_count() < m_config.m_net_config.max_out_connection_count
+ && make_expected_connections_count(gray, m_config.m_net_config.max_out_connection_count));
}else
{
//start from grey list
- if(!make_expected_connections_count(gray, m_config.m_net_config.max_out_connection_count))
- return false;
+ while (get_outgoing_connections_count() < m_config.m_net_config.max_out_connection_count
+ && make_expected_connections_count(gray, m_config.m_net_config.max_out_connection_count));
//and then do white list
- if(!make_expected_connections_count(white, m_config.m_net_config.max_out_connection_count))
- return false;
+ while (get_outgoing_connections_count() < m_config.m_net_config.max_out_connection_count
+ && make_expected_connections_count(white, m_config.m_net_config.max_out_connection_count));
}
+ if(m_net_server.is_stop_signal_sent())
+ return false;
+ conn_count = get_outgoing_connections_count();
}
if (start_conn_count == get_outgoing_connections_count() && start_conn_count < m_config.m_net_config.max_out_connection_count)
@@ -1260,7 +1324,7 @@ namespace nodetool
bool node_server<t_payload_net_handler>::make_expected_connections_count(PeerType peer_type, size_t expected_connections)
{
if (m_offline)
- return true;
+ return false;
std::vector<anchor_peerlist_entry> apl;
@@ -1270,24 +1334,24 @@ namespace nodetool
size_t conn_count = get_outgoing_connections_count();
//add new connections from white peers
- while(conn_count < expected_connections)
+ if(conn_count < expected_connections)
{
if(m_net_server.is_stop_signal_sent())
return false;
+ MDEBUG("Making expected connection, type " << peer_type << ", " << conn_count << "/" << expected_connections << " connections");
+
if (peer_type == anchor && !make_new_connection_from_anchor_peerlist(apl)) {
- break;
+ return false;
}
if (peer_type == white && !make_new_connection_from_peerlist(true)) {
- break;
+ return false;
}
if (peer_type == gray && !make_new_connection_from_peerlist(false)) {
- break;
+ return false;
}
-
- conn_count = get_outgoing_connections_count();
}
return true;
}
@@ -1390,6 +1454,9 @@ namespace nodetool
return false;
}
be.last_seen += delta;
+#ifdef CRYPTONOTE_PRUNING_DEBUG_SPOOF_SEED
+ be.pruning_seed = tools::make_pruning_seed(1 + (be.adr.as<epee::net_utils::ipv4_network_address>().ip()) % (1ul << CRYPTONOTE_PRUNING_LOG_STRIPES), CRYPTONOTE_PRUNING_LOG_STRIPES);
+#endif
}
return true;
}
@@ -1750,6 +1817,7 @@ namespace nodetool
time(&last_seen);
pe.last_seen = static_cast<int64_t>(last_seen);
pe.id = peer_id_l;
+ pe.pruning_seed = context.m_pruning_seed;
this->m_peerlist.append_with_peer_white(pe);
LOG_DEBUG_CC(context, "PING SUCCESS " << context.m_remote_address.host_str() << ":" << port_l);
});
@@ -1885,21 +1953,16 @@ namespace nodetool
template<class t_payload_net_handler>
bool node_server<t_payload_net_handler>::set_max_out_peers(const boost::program_options::variables_map& vm, int64_t max)
{
- if(max == -1) {
- m_config.m_net_config.max_out_connection_count = P2P_DEFAULT_CONNECTIONS_COUNT;
- return true;
- }
+ if(max == -1)
+ max = P2P_DEFAULT_CONNECTIONS_COUNT;
m_config.m_net_config.max_out_connection_count = max;
+ m_payload_handler.set_max_out_peers(max);
return true;
}
template<class t_payload_net_handler>
bool node_server<t_payload_net_handler>::set_max_in_peers(const boost::program_options::variables_map& vm, int64_t max)
{
- if(max == -1) {
- m_config.m_net_config.max_in_connection_count = -1;
- return true;
- }
m_config.m_net_config.max_in_connection_count = max;
return true;
}
@@ -2010,6 +2073,7 @@ namespace nodetool
{
if (m_offline) return true;
if (!m_exclusive_peers.empty()) return true;
+ if (m_payload_handler.needs_new_sync_connections()) return true;
peerlist_entry pe = AUTO_VAL_INIT(pe);
@@ -2030,7 +2094,7 @@ namespace nodetool
return true;
}
- m_peerlist.set_peer_just_seen(pe.id, pe.adr);
+ m_peerlist.set_peer_just_seen(pe.id, pe.adr, pe.pruning_seed);
LOG_PRINT_L2("PEER PROMOTED TO WHITE PEER LIST IP address: " << pe.adr.host_str() << " Peer ID: " << peerid_type(pe.id));
@@ -2038,6 +2102,42 @@ namespace nodetool
}
template<class t_payload_net_handler>
+ void node_server<t_payload_net_handler>::add_used_stripe_peer(const typename t_payload_net_handler::connection_context &context)
+ {
+ const uint32_t stripe = tools::get_pruning_stripe(context.m_pruning_seed);
+ if (stripe == 0 || stripe > (1ul << CRYPTONOTE_PRUNING_LOG_STRIPES))
+ return;
+ const uint32_t index = stripe - 1;
+ CRITICAL_REGION_LOCAL(m_used_stripe_peers_mutex);
+ MINFO("adding stripe " << stripe << " peer: " << context.m_remote_address.str());
+ std::remove_if(m_used_stripe_peers[index].begin(), m_used_stripe_peers[index].end(),
+ [&context](const epee::net_utils::network_address &na){ return context.m_remote_address == na; });
+ m_used_stripe_peers[index].push_back(context.m_remote_address);
+ }
+
+ template<class t_payload_net_handler>
+ void node_server<t_payload_net_handler>::remove_used_stripe_peer(const typename t_payload_net_handler::connection_context &context)
+ {
+ const uint32_t stripe = tools::get_pruning_stripe(context.m_pruning_seed);
+ if (stripe == 0 || stripe > (1ul << CRYPTONOTE_PRUNING_LOG_STRIPES))
+ return;
+ const uint32_t index = stripe - 1;
+ CRITICAL_REGION_LOCAL(m_used_stripe_peers_mutex);
+ MINFO("removing stripe " << stripe << " peer: " << context.m_remote_address.str());
+ std::remove_if(m_used_stripe_peers[index].begin(), m_used_stripe_peers[index].end(),
+ [&context](const epee::net_utils::network_address &na){ return context.m_remote_address == na; });
+ }
+
+ template<class t_payload_net_handler>
+ void node_server<t_payload_net_handler>::clear_used_stripe_peers()
+ {
+ CRITICAL_REGION_LOCAL(m_used_stripe_peers_mutex);
+ MINFO("clearing used stripe peers");
+ for (auto &e: m_used_stripe_peers)
+ e.clear();
+ }
+
+ template<class t_payload_net_handler>
void node_server<t_payload_net_handler>::add_upnp_port_mapping(uint32_t port)
{
MDEBUG("Attempting to add IGD port mapping.");
diff --git a/src/p2p/net_node_common.h b/src/p2p/net_node_common.h
index 656c6155b..075c18ef9 100644
--- a/src/p2p/net_node_common.h
+++ b/src/p2p/net_node_common.h
@@ -56,6 +56,9 @@ namespace nodetool
virtual bool unblock_host(const epee::net_utils::network_address &address)=0;
virtual std::map<std::string, time_t> get_blocked_hosts()=0;
virtual bool add_host_fail(const epee::net_utils::network_address &address)=0;
+ virtual void add_used_stripe_peer(const t_connection_context &context)=0;
+ virtual void remove_used_stripe_peer(const t_connection_context &context)=0;
+ virtual void clear_used_stripe_peers()=0;
};
template<class t_connection_context>
@@ -114,5 +117,14 @@ namespace nodetool
{
return true;
}
+ virtual void add_used_stripe_peer(const t_connection_context &context)
+ {
+ }
+ virtual void remove_used_stripe_peer(const t_connection_context &context)
+ {
+ }
+ virtual void clear_used_stripe_peers()
+ {
+ }
};
}
diff --git a/src/p2p/net_peerlist.h b/src/p2p/net_peerlist.h
index e7aad5abe..685fdc193 100644
--- a/src/p2p/net_peerlist.h
+++ b/src/p2p/net_peerlist.h
@@ -73,16 +73,18 @@ namespace nodetool
bool get_peerlist_full(std::vector<peerlist_entry>& pl_gray, std::vector<peerlist_entry>& pl_white);
bool get_white_peer_by_index(peerlist_entry& p, size_t i);
bool get_gray_peer_by_index(peerlist_entry& p, size_t i);
+ template<typename F> bool foreach(bool white, const F &f);
bool append_with_peer_white(const peerlist_entry& pr);
bool append_with_peer_gray(const peerlist_entry& pr);
bool append_with_peer_anchor(const anchor_peerlist_entry& ple);
- bool set_peer_just_seen(peerid_type peer, const epee::net_utils::network_address& addr);
+ bool set_peer_just_seen(peerid_type peer, const epee::net_utils::network_address& addr, uint32_t pruning_seed);
bool set_peer_unreachable(const peerlist_entry& pr);
bool is_host_allowed(const epee::net_utils::network_address &address);
bool get_random_gray_peer(peerlist_entry& pe);
bool remove_from_peer_gray(const peerlist_entry& pe);
bool get_and_empty_anchor_peerlist(std::vector<anchor_peerlist_entry>& apl);
bool remove_from_peer_anchor(const epee::net_utils::network_address& addr);
+ bool remove_from_peer_white(const peerlist_entry& pe);
private:
struct by_time{};
@@ -356,8 +358,19 @@ namespace nodetool
return true;
}
//--------------------------------------------------------------------------------------------------
+ template<typename F> inline
+ bool peerlist_manager::foreach(bool white, const F &f)
+ {
+ CRITICAL_REGION_LOCAL(m_peerlist_lock);
+ peers_indexed::index<by_time>::type& by_time_index = white ? m_peers_white.get<by_time>() : m_peers_gray.get<by_time>();
+ for(const peers_indexed::value_type& vl: boost::adaptors::reverse(by_time_index))
+ if (!f(vl))
+ return false;
+ return true;
+ }
+ //--------------------------------------------------------------------------------------------------
inline
- bool peerlist_manager::set_peer_just_seen(peerid_type peer, const epee::net_utils::network_address& addr)
+ bool peerlist_manager::set_peer_just_seen(peerid_type peer, const epee::net_utils::network_address& addr, uint32_t pruning_seed)
{
TRY_ENTRY();
CRITICAL_REGION_LOCAL(m_peerlist_lock);
@@ -366,6 +379,7 @@ namespace nodetool
ple.adr = addr;
ple.id = peer;
ple.last_seen = time(NULL);
+ ple.pruning_seed = pruning_seed;
return append_with_peer_white(ple);
CATCH_ENTRY_L0("peerlist_manager::set_peer_just_seen()", false);
}
@@ -469,6 +483,24 @@ namespace nodetool
}
//--------------------------------------------------------------------------------------------------
inline
+ bool peerlist_manager::remove_from_peer_white(const peerlist_entry& pe)
+ {
+ TRY_ENTRY();
+
+ CRITICAL_REGION_LOCAL(m_peerlist_lock);
+
+ peers_indexed::index_iterator<by_addr>::type iterator = m_peers_white.get<by_addr>().find(pe.adr);
+
+ if (iterator != m_peers_white.get<by_addr>().end()) {
+ m_peers_white.erase(iterator);
+ }
+
+ return true;
+
+ CATCH_ENTRY_L0("peerlist_manager::remove_from_peer_white()", false);
+ }
+ //--------------------------------------------------------------------------------------------------
+ inline
bool peerlist_manager::remove_from_peer_gray(const peerlist_entry& pe)
{
TRY_ENTRY();
diff --git a/src/p2p/net_peerlist_boost_serialization.h b/src/p2p/net_peerlist_boost_serialization.h
index e79207888..2f4a7e661 100644
--- a/src/p2p/net_peerlist_boost_serialization.h
+++ b/src/p2p/net_peerlist_boost_serialization.h
@@ -33,6 +33,10 @@
#include "net/net_utils_base.h"
#include "p2p/p2p_protocol_defs.h"
+#ifdef CRYPTONOTE_PRUNING_DEBUG_SPOOF_SEED
+#include "common/pruning.h"
+#endif
+
namespace boost
{
namespace serialization
@@ -77,6 +81,19 @@ namespace boost
a & pl.adr;
a & pl.id;
a & pl.last_seen;
+ if (ver < 1)
+ {
+ if (!typename Archive::is_saving())
+ pl.pruning_seed = 0;
+ return;
+ }
+ a & pl.pruning_seed;
+#ifdef CRYPTONOTE_PRUNING_DEBUG_SPOOF_SEED
+ if (!typename Archive::is_saving())
+ {
+ pl.pruning_seed = tools::make_pruning_seed(1+pl.adr.as<epee::net_utils::ipv4_network_address>().ip() % (1<<CRYPTONOTE_PRUNING_LOG_STRIPES), CRYPTONOTE_PRUNING_LOG_STRIPES);
+ }
+#endif
}
template <class Archive, class ver_type>
diff --git a/src/p2p/p2p_protocol_defs.h b/src/p2p/p2p_protocol_defs.h
index bb9d2635c..939cedf42 100644
--- a/src/p2p/p2p_protocol_defs.h
+++ b/src/p2p/p2p_protocol_defs.h
@@ -31,6 +31,7 @@
#pragma once
#include <boost/uuid/uuid.hpp>
+#include <boost/serialization/version.hpp>
#include "serialization/keyvalue_serialization.h"
#include "net/net_utils_base.h"
#include "misc_language.h"
@@ -72,11 +73,13 @@ namespace nodetool
AddressType adr;
peerid_type id;
int64_t last_seen;
+ uint32_t pruning_seed;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(adr)
KV_SERIALIZE(id)
KV_SERIALIZE(last_seen)
+ KV_SERIALIZE_OPT(pruning_seed, (uint32_t)0)
END_KV_SERIALIZE_MAP()
};
typedef peerlist_entry_base<epee::net_utils::network_address> peerlist_entry;
@@ -122,7 +125,7 @@ namespace nodetool
ss << std::setfill ('0') << std::setw (8) << std::hex << std::noshowbase;
for(const peerlist_entry& pe: pl)
{
- ss << pe.id << "\t" << pe.adr.str() << " \tlast_seen: " << epee::misc_utils::get_time_interval_string(now_time - pe.last_seen) << std::endl;
+ ss << pe.id << "\t" << pe.adr.str() << " \tpruning seed " << pe.pruning_seed << " \tlast_seen: " << epee::misc_utils::get_time_interval_string(now_time - pe.last_seen) << std::endl;
}
return ss.str();
}
@@ -205,7 +208,7 @@ namespace nodetool
{
const epee::net_utils::network_address &na = p.adr;
const epee::net_utils::ipv4_network_address &ipv4 = na.as<const epee::net_utils::ipv4_network_address>();
- local_peerlist.push_back(peerlist_entry_base<network_address_old>({{ipv4.ip(), ipv4.port()}, p.id, p.last_seen}));
+ local_peerlist.push_back(peerlist_entry_base<network_address_old>({{ipv4.ip(), ipv4.port()}, p.id, p.last_seen, p.pruning_seed}));
}
else
MDEBUG("Not including in legacy peer list: " << p.adr.str());
@@ -220,7 +223,7 @@ namespace nodetool
std::vector<peerlist_entry_base<network_address_old>> local_peerlist;
epee::serialization::selector<is_store>::serialize_stl_container_pod_val_as_blob(local_peerlist, stg, hparent_section, "local_peerlist");
for (const auto &p: local_peerlist)
- ((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}));
+ ((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}));
}
}
END_KV_SERIALIZE_MAP()
@@ -463,5 +466,6 @@ namespace nodetool
}
+BOOST_CLASS_VERSION(nodetool::peerlist_entry, 1)