aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/blocks/checkpoints.datbin279428 -> 280452 bytes
-rw-r--r--src/checkpoints/checkpoints.cpp1
-rw-r--r--src/crypto/crypto.cpp12
-rw-r--r--src/cryptonote_basic/connection_context.h6
-rw-r--r--src/cryptonote_config.h1
-rw-r--r--src/cryptonote_core/blockchain.cpp2
-rw-r--r--src/cryptonote_protocol/block_queue.cpp15
-rw-r--r--src/cryptonote_protocol/block_queue.h18
-rw-r--r--src/cryptonote_protocol/cryptonote_protocol_handler.h7
-rw-r--r--src/cryptonote_protocol/cryptonote_protocol_handler.inl145
-rw-r--r--src/p2p/net_node.h4
-rw-r--r--src/p2p/net_node.inl110
-rw-r--r--src/p2p/net_node_common.h4
-rw-r--r--src/p2p/net_peerlist.cpp13
-rw-r--r--src/p2p/net_peerlist.h2
-rw-r--r--src/rpc/core_rpc_server.cpp6
-rw-r--r--src/version.cpp.in2
-rw-r--r--src/wallet/wallet2.cpp3
18 files changed, 254 insertions, 97 deletions
diff --git a/src/blocks/checkpoints.dat b/src/blocks/checkpoints.dat
index bcbfbb7ee..7f5f996cb 100644
--- a/src/blocks/checkpoints.dat
+++ b/src/blocks/checkpoints.dat
Binary files differ
diff --git a/src/checkpoints/checkpoints.cpp b/src/checkpoints/checkpoints.cpp
index d966eebda..d4733007b 100644
--- a/src/checkpoints/checkpoints.cpp
+++ b/src/checkpoints/checkpoints.cpp
@@ -242,6 +242,7 @@ namespace cryptonote
ADD_CHECKPOINT2(2210500, "ed17259215ac6aabe6e8252b5b5eff613d2e69cc2111173e567109aa78301911", "0xfbcb50a9a6a433");
ADD_CHECKPOINT2(2224000, "e34bc71301600df96d08aaa6b0bde932cba1b06a3dd57076e3f664a078810a80", "0x1052fc256fceb6f");
ADD_CHECKPOINT2(2235500, "3eac1a1253495733e10d00fd5e8e1639741566d91bae38bc6d3342af6b75da53", "0x10cea232ce71d23");
+ ADD_CHECKPOINT2(2244000, "f06b8a19a75070cd002414d9d3ce59cf6b11ed9db464c6b84d3f22abbff84fae", "0x112b3331539f585");
return true;
}
diff --git a/src/crypto/crypto.cpp b/src/crypto/crypto.cpp
index 4cfe83d54..0059dd7f5 100644
--- a/src/crypto/crypto.cpp
+++ b/src/crypto/crypto.cpp
@@ -123,13 +123,17 @@ namespace crypto {
void random32_unbiased(unsigned char *bytes)
{
// l = 2^252 + 27742317777372353535851937790883648493.
- // it fits 15 in 32 bytes
+ // l fits 15 times in 32 bytes (iow, 15 l is the highest multiple of l that fits in 32 bytes)
static const unsigned char limit[32] = { 0xe3, 0x6a, 0x67, 0x72, 0x8b, 0xce, 0x13, 0x29, 0x8f, 0x30, 0x82, 0x8c, 0x0b, 0xa4, 0x10, 0x39, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0 };
- do
+ while(1)
{
generate_random_bytes_thread_safe(32, bytes);
- } while (!sc_isnonzero(bytes) && !less32(bytes, limit)); // should be good about 15/16 of the time
- sc_reduce32(bytes);
+ if (!less32(bytes, limit))
+ continue;
+ sc_reduce32(bytes);
+ if (sc_isnonzero(bytes))
+ break;
+ }
}
/* generate a random 32-byte (256-bit) integer and copy it to res */
static inline void random_scalar(ec_scalar &res) {
diff --git a/src/cryptonote_basic/connection_context.h b/src/cryptonote_basic/connection_context.h
index 0c3a94054..8d26e5638 100644
--- a/src/cryptonote_basic/connection_context.h
+++ b/src/cryptonote_basic/connection_context.h
@@ -43,7 +43,8 @@ namespace cryptonote
{
cryptonote_connection_context(): m_state(state_before_handshake), m_remote_blockchain_height(0), m_last_response_height(0),
m_last_request_time(boost::date_time::not_a_date_time), m_callback_request_count(0),
- m_last_known_hash(crypto::null_hash), m_pruning_seed(0), m_rpc_port(0), m_rpc_credits_per_hash(0), m_anchor(false) {}
+ m_last_known_hash(crypto::null_hash), m_pruning_seed(0), m_rpc_port(0), m_rpc_credits_per_hash(0), m_anchor(false), m_score(0),
+ m_expect_response(0) {}
enum state
{
@@ -66,7 +67,8 @@ namespace cryptonote
uint16_t m_rpc_port;
uint32_t m_rpc_credits_per_hash;
bool m_anchor;
- //size_t m_score; TODO: add score calculations
+ int32_t m_score;
+ int m_expect_response;
};
inline std::string get_protocol_state_string(cryptonote_connection_context::state s)
diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h
index 826cabe17..13f0c471b 100644
--- a/src/cryptonote_config.h
+++ b/src/cryptonote_config.h
@@ -132,6 +132,7 @@
#define P2P_DEFAULT_HANDSHAKE_INTERVAL 60 //secondes
#define P2P_DEFAULT_PACKET_MAX_SIZE 50000000 //50000000 bytes maximum packet size
#define P2P_DEFAULT_PEERS_IN_HANDSHAKE 250
+#define P2P_MAX_PEERS_IN_HANDSHAKE 250
#define P2P_DEFAULT_CONNECTION_TIMEOUT 5000 //5 seconds
#define P2P_DEFAULT_SOCKS_CONNECT_TIMEOUT 45 // seconds
#define P2P_DEFAULT_PING_CONNECTION_TIMEOUT 2000 //2 seconds
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index 89ecda2cd..78fc57967 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -5376,7 +5376,7 @@ void Blockchain::cancel()
}
#if defined(PER_BLOCK_CHECKPOINT)
-static const char expected_block_hashes_hash[] = "3a2a0720f7ed3573d2b632f7ba127e2f97edac3af34bf924df57c13a88bf2460";
+static const char expected_block_hashes_hash[] = "6a6436850ed9df5975ca0c45513647c3d401ed8523ff5a793ad93136fa34fd3b";
void Blockchain::load_compiled_in_block_hashes(const GetCheckpointsCallback& get_checkpoints)
{
if (get_checkpoints == nullptr || !m_fast_sync)
diff --git a/src/cryptonote_protocol/block_queue.cpp b/src/cryptonote_protocol/block_queue.cpp
index bbde91c1f..2f5b693dd 100644
--- a/src/cryptonote_protocol/block_queue.cpp
+++ b/src/cryptonote_protocol/block_queue.cpp
@@ -52,12 +52,12 @@ namespace std {
namespace cryptonote
{
-void block_queue::add_blocks(uint64_t height, std::vector<cryptonote::block_complete_entry> bcel, const boost::uuids::uuid &connection_id, float rate, size_t size)
+void block_queue::add_blocks(uint64_t height, std::vector<cryptonote::block_complete_entry> bcel, const boost::uuids::uuid &connection_id, const epee::net_utils::network_address &addr, float rate, size_t size)
{
boost::unique_lock<boost::recursive_mutex> lock(mutex);
std::vector<crypto::hash> hashes;
bool has_hashes = remove_span(height, &hashes);
- blocks.insert(span(height, std::move(bcel), connection_id, rate, size));
+ blocks.insert(span(height, std::move(bcel), connection_id, addr, rate, size));
if (has_hashes)
{
for (const crypto::hash &h: hashes)
@@ -69,11 +69,11 @@ void block_queue::add_blocks(uint64_t height, std::vector<cryptonote::block_comp
}
}
-void block_queue::add_blocks(uint64_t height, uint64_t nblocks, const boost::uuids::uuid &connection_id, boost::posix_time::ptime time)
+void block_queue::add_blocks(uint64_t height, uint64_t nblocks, const boost::uuids::uuid &connection_id, const epee::net_utils::network_address &addr, boost::posix_time::ptime time)
{
CHECK_AND_ASSERT_THROW_MES(nblocks > 0, "Empty span");
boost::unique_lock<boost::recursive_mutex> lock(mutex);
- blocks.insert(span(height, nblocks, connection_id, time));
+ blocks.insert(span(height, nblocks, connection_id, addr, time));
}
void block_queue::flush_spans(const boost::uuids::uuid &connection_id, bool all)
@@ -228,7 +228,7 @@ bool block_queue::have(const crypto::hash &hash) const
return have_blocks.find(hash) != have_blocks.end();
}
-std::pair<uint64_t, uint64_t> block_queue::reserve_span(uint64_t first_block_height, uint64_t last_block_height, uint64_t max_blocks, const boost::uuids::uuid &connection_id, bool sync_pruned_blocks, uint32_t local_pruning_seed, uint32_t pruning_seed, uint64_t blockchain_height, const std::vector<std::pair<crypto::hash, uint64_t>> &block_hashes, boost::posix_time::ptime time)
+std::pair<uint64_t, uint64_t> block_queue::reserve_span(uint64_t first_block_height, uint64_t last_block_height, uint64_t max_blocks, const boost::uuids::uuid &connection_id, const epee::net_utils::network_address &addr, bool sync_pruned_blocks, uint32_t local_pruning_seed, uint32_t pruning_seed, uint64_t blockchain_height, const std::vector<std::pair<crypto::hash, uint64_t>> &block_hashes, boost::posix_time::ptime time)
{
boost::unique_lock<boost::recursive_mutex> lock(mutex);
@@ -305,7 +305,7 @@ std::pair<uint64_t, uint64_t> block_queue::reserve_span(uint64_t first_block_hei
return std::make_pair(0, 0);
}
MDEBUG("Reserving span " << span_start_height << " - " << (span_start_height + span_length - 1) << " for " << connection_id);
- add_blocks(span_start_height, span_length, connection_id, time);
+ add_blocks(span_start_height, span_length, connection_id, addr, time);
set_span_hashes(span_start_height, connection_id, hashes);
return std::make_pair(span_start_height, span_length);
}
@@ -354,7 +354,7 @@ void block_queue::set_span_hashes(uint64_t start_height, const boost::uuids::uui
}
}
-bool block_queue::get_next_span(uint64_t &height, std::vector<cryptonote::block_complete_entry> &bcel, boost::uuids::uuid &connection_id, bool filled) const
+bool block_queue::get_next_span(uint64_t &height, std::vector<cryptonote::block_complete_entry> &bcel, boost::uuids::uuid &connection_id, epee::net_utils::network_address &addr, bool filled) const
{
boost::unique_lock<boost::recursive_mutex> lock(mutex);
if (blocks.empty())
@@ -367,6 +367,7 @@ bool block_queue::get_next_span(uint64_t &height, std::vector<cryptonote::block_
height = i->start_block_height;
bcel = i->blocks;
connection_id = i->connection_id;
+ addr = i->origin;
return true;
}
}
diff --git a/src/cryptonote_protocol/block_queue.h b/src/cryptonote_protocol/block_queue.h
index 57d2a6490..30fb5bc21 100644
--- a/src/cryptonote_protocol/block_queue.h
+++ b/src/cryptonote_protocol/block_queue.h
@@ -36,6 +36,7 @@
#include <unordered_set>
#include <boost/thread/recursive_mutex.hpp>
#include <boost/uuid/uuid.hpp>
+#include "net/net_utils_base.h"
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "cn.block_queue"
@@ -57,19 +58,20 @@ namespace cryptonote
float rate;
size_t size;
boost::posix_time::ptime time;
+ epee::net_utils::network_address origin{};
- span(uint64_t start_block_height, std::vector<cryptonote::block_complete_entry> blocks, const boost::uuids::uuid &connection_id, float rate, size_t size):
- start_block_height(start_block_height), blocks(std::move(blocks)), connection_id(connection_id), nblocks(this->blocks.size()), rate(rate), size(size), time() {}
- span(uint64_t start_block_height, uint64_t nblocks, const boost::uuids::uuid &connection_id, boost::posix_time::ptime time):
- start_block_height(start_block_height), connection_id(connection_id), nblocks(nblocks), rate(0.0f), size(0), time(time) {}
+ span(uint64_t start_block_height, std::vector<cryptonote::block_complete_entry> blocks, const boost::uuids::uuid &connection_id, const epee::net_utils::network_address &addr, float rate, size_t size):
+ start_block_height(start_block_height), blocks(std::move(blocks)), connection_id(connection_id), nblocks(this->blocks.size()), rate(rate), size(size), time(boost::date_time::min_date_time), origin(addr) {}
+ span(uint64_t start_block_height, uint64_t nblocks, const boost::uuids::uuid &connection_id, const epee::net_utils::network_address &addr, boost::posix_time::ptime time):
+ start_block_height(start_block_height), connection_id(connection_id), nblocks(nblocks), rate(0.0f), size(0), time(time), origin(addr) {}
bool operator<(const span &s) const { return start_block_height < s.start_block_height; }
};
typedef std::set<span> block_map;
public:
- void add_blocks(uint64_t height, std::vector<cryptonote::block_complete_entry> bcel, const boost::uuids::uuid &connection_id, float rate, size_t size);
- void add_blocks(uint64_t height, uint64_t nblocks, const boost::uuids::uuid &connection_id, boost::posix_time::ptime time = boost::date_time::min_date_time);
+ void add_blocks(uint64_t height, std::vector<cryptonote::block_complete_entry> bcel, const boost::uuids::uuid &connection_id, const epee::net_utils::network_address &addr, float rate, size_t size);
+ void add_blocks(uint64_t height, uint64_t nblocks, const boost::uuids::uuid &connection_id, const epee::net_utils::network_address &addr, boost::posix_time::ptime time = boost::date_time::min_date_time);
void flush_spans(const boost::uuids::uuid &connection_id, bool all = false);
void flush_stale_spans(const std::set<boost::uuids::uuid> &live_connections);
bool remove_span(uint64_t start_block_height, std::vector<crypto::hash> *hashes = NULL);
@@ -78,12 +80,12 @@ namespace cryptonote
void print() const;
std::string get_overview(uint64_t blockchain_height) const;
bool has_unpruned_height(uint64_t block_height, uint64_t blockchain_height, uint32_t pruning_seed) const;
- std::pair<uint64_t, uint64_t> reserve_span(uint64_t first_block_height, uint64_t last_block_height, uint64_t max_blocks, const boost::uuids::uuid &connection_id, bool sync_pruned_blocks, uint32_t local_pruning_seed, uint32_t pruning_seed, uint64_t blockchain_height, const std::vector<std::pair<crypto::hash, uint64_t>> &block_hashes, boost::posix_time::ptime time = boost::posix_time::microsec_clock::universal_time());
+ std::pair<uint64_t, uint64_t> reserve_span(uint64_t first_block_height, uint64_t last_block_height, uint64_t max_blocks, const boost::uuids::uuid &connection_id, const epee::net_utils::network_address &addr, bool sync_pruned_blocks, uint32_t local_pruning_seed, uint32_t pruning_seed, uint64_t blockchain_height, const std::vector<std::pair<crypto::hash, uint64_t>> &block_hashes, boost::posix_time::ptime time = boost::posix_time::microsec_clock::universal_time());
uint64_t get_next_needed_height(uint64_t blockchain_height) const;
std::pair<uint64_t, uint64_t> get_next_span_if_scheduled(std::vector<crypto::hash> &hashes, boost::uuids::uuid &connection_id, boost::posix_time::ptime &time) const;
void reset_next_span_time(boost::posix_time::ptime t = boost::posix_time::microsec_clock::universal_time());
void set_span_hashes(uint64_t start_height, const boost::uuids::uuid &connection_id, std::vector<crypto::hash> hashes);
- bool get_next_span(uint64_t &height, std::vector<cryptonote::block_complete_entry> &bcel, boost::uuids::uuid &connection_id, bool filled = true) const;
+ bool get_next_span(uint64_t &height, std::vector<cryptonote::block_complete_entry> &bcel, boost::uuids::uuid &connection_id, epee::net_utils::network_address &addr, bool filled = true) const;
bool has_next_span(const boost::uuids::uuid &connection_id, bool &filled, boost::posix_time::ptime &time) const;
bool has_next_span(uint64_t height, bool &filled, boost::posix_time::ptime &time, boost::uuids::uuid &connection_id) const;
size_t get_data_size() const;
diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.h b/src/cryptonote_protocol/cryptonote_protocol_handler.h
index 61aac6d81..b416b86c8 100644
--- a/src/cryptonote_protocol/cryptonote_protocol_handler.h
+++ b/src/cryptonote_protocol/cryptonote_protocol_handler.h
@@ -141,6 +141,7 @@ namespace cryptonote
bool should_ask_for_pruned_data(cryptonote_connection_context& context, uint64_t first_block_height, uint64_t nblocks, bool check_block_weights) const;
void drop_connection(cryptonote_connection_context &context, bool add_fail, bool flush_all_spans);
void drop_connection_with_score(cryptonote_connection_context &context, unsigned int score, bool flush_all_spans);
+ void drop_connections(const epee::net_utils::network_address address);
bool kick_idle_peers();
bool check_standby_peers();
bool update_sync_search();
@@ -148,6 +149,7 @@ namespace cryptonote
void notify_new_stripe(cryptonote_connection_context &context, uint32_t stripe);
void skip_unneeded_hashes(cryptonote_connection_context& context, bool check_block_queue) const;
bool request_txpool_complement(cryptonote_connection_context &context);
+ void hit_score(cryptonote_connection_context &context, int32_t score);
t_core& m_core;
@@ -160,9 +162,10 @@ namespace cryptonote
std::atomic<bool> m_ask_for_txpool_complement;
boost::mutex m_sync_lock;
block_queue m_block_queue;
- epee::math_helper::once_a_time_seconds<30> m_idle_peer_kicker;
+ epee::math_helper::once_a_time_seconds<8> m_idle_peer_kicker;
epee::math_helper::once_a_time_milliseconds<100> m_standby_checker;
epee::math_helper::once_a_time_seconds<101> m_sync_search_checker;
+ epee::math_helper::once_a_time_seconds<43> m_bad_peer_checker;
std::atomic<unsigned int> m_max_out_peers;
tools::PerformanceTimer m_sync_timer, m_add_timer;
uint64_t m_last_add_end_time;
@@ -183,6 +186,8 @@ namespace cryptonote
double get_avg_block_size();
boost::circular_buffer<size_t> m_avg_buffer = boost::circular_buffer<size_t>(10);
+ boost::mutex m_bad_peer_check_lock;
+
template<class t_parameter>
bool post_notify(typename t_parameter::request& arg, cryptonote_connection_context& context)
{
diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl
index a72b7db79..37157e637 100644
--- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl
+++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl
@@ -68,10 +68,12 @@
#define BLOCK_QUEUE_FORCE_DOWNLOAD_NEAR_BLOCKS 1000
#define REQUEST_NEXT_SCHEDULED_SPAN_THRESHOLD_STANDBY (5 * 1000000) // microseconds
#define REQUEST_NEXT_SCHEDULED_SPAN_THRESHOLD (30 * 1000000) // microseconds
-#define IDLE_PEER_KICK_TIME (600 * 1000000) // microseconds
+#define IDLE_PEER_KICK_TIME (240 * 1000000) // microseconds
+#define NON_RESPONSIVE_PEER_KICK_TIME (20 * 1000000) // microseconds
#define PASSIVE_PEER_KICK_TIME (60 * 1000000) // microseconds
#define DROP_ON_SYNC_WEDGE_THRESHOLD (30 * 1000000000ull) // nanoseconds
#define LAST_ACTIVITY_STALL_THRESHOLD (2.0f) // seconds
+#define DROP_PEERS_ON_SCORE -2
namespace cryptonote
{
@@ -142,6 +144,8 @@ namespace cryptonote
m_core.get_short_chain_history(r.block_ids);
handler_request_blocks_history( r.block_ids ); // change the limit(?), sleep(?)
r.prune = m_sync_pruned_blocks;
+ context.m_last_request_time = boost::posix_time::microsec_clock::universal_time();
+ context.m_expect_response = NOTIFY_RESPONSE_CHAIN_ENTRY::ID;
MLOG_P2P_MESSAGE("-->>NOTIFY_REQUEST_CHAIN: m_block_ids.size()=" << r.block_ids.size() );
post_notify<NOTIFY_REQUEST_CHAIN>(r, context);
MLOG_PEER_STATE("requesting chain");
@@ -326,6 +330,11 @@ namespace cryptonote
}
}
+ if (hshd.current_height < context.m_remote_blockchain_height)
+ {
+ MINFO(context << "Claims " << hshd.current_height << ", claimed " << context.m_remote_blockchain_height << " before");
+ hit_score(context, 1);
+ }
context.m_remote_blockchain_height = hshd.current_height;
context.m_pruning_seed = hshd.pruning_seed;
#ifdef CRYPTONOTE_PRUNING_DEBUG_SPOOF_SEED
@@ -427,7 +436,7 @@ namespace cryptonote
template<class t_core>
int t_cryptonote_protocol_handler<t_core>::handle_notify_new_block(int command, NOTIFY_NEW_BLOCK::request& arg, cryptonote_connection_context& context)
{
- MLOGIF_P2P_MESSAGE(crypto::hash hash; cryptonote::block b; bool ret = cryptonote::parse_and_validate_block_from_blob(arg.b.block, b, &hash);, ret, "Received NOTIFY_NEW_BLOCK " << hash << " (height " << arg.current_blockchain_height << ", " << arg.b.txs.size() << " txes)");
+ MLOGIF_P2P_MESSAGE(crypto::hash hash; cryptonote::block b; bool ret = cryptonote::parse_and_validate_block_from_blob(arg.b.block, b, &hash);, ret, context << "Received NOTIFY_NEW_BLOCK " << hash << " (height " << arg.current_blockchain_height << ", " << arg.b.txs.size() << " txes)");
if(context.m_state != cryptonote_connection_context::state_normal)
return 1;
if(!is_synchronized()) // can happen if a peer connection goes to normal but another thread still hasn't finished adding queued blocks
@@ -487,6 +496,8 @@ namespace cryptonote
m_core.get_short_chain_history(r.block_ids);
r.prune = m_sync_pruned_blocks;
handler_request_blocks_history( r.block_ids ); // change the limit(?), sleep(?)
+ context.m_last_request_time = boost::posix_time::microsec_clock::universal_time();
+ context.m_expect_response = NOTIFY_RESPONSE_CHAIN_ENTRY::ID;
MLOG_P2P_MESSAGE("-->>NOTIFY_REQUEST_CHAIN: m_block_ids.size()=" << r.block_ids.size() );
post_notify<NOTIFY_REQUEST_CHAIN>(r, context);
MLOG_PEER_STATE("requesting chain");
@@ -498,7 +509,7 @@ namespace cryptonote
template<class t_core>
int t_cryptonote_protocol_handler<t_core>::handle_notify_new_fluffy_block(int command, NOTIFY_NEW_FLUFFY_BLOCK::request& arg, cryptonote_connection_context& context)
{
- MLOGIF_P2P_MESSAGE(crypto::hash hash; cryptonote::block b; bool ret = cryptonote::parse_and_validate_block_from_blob(arg.b.block, b, &hash);, ret, "Received NOTIFY_NEW_FLUFFY_BLOCK " << hash << " (height " << arg.current_blockchain_height << ", " << arg.b.txs.size() << " txes)");
+ MLOGIF_P2P_MESSAGE(crypto::hash hash; cryptonote::block b; bool ret = cryptonote::parse_and_validate_block_from_blob(arg.b.block, b, &hash);, ret, context << "Received NOTIFY_NEW_FLUFFY_BLOCK " << hash << " (height " << arg.current_blockchain_height << ", " << arg.b.txs.size() << " txes)");
if(context.m_state != cryptonote_connection_context::state_normal)
return 1;
if(!is_synchronized()) // can happen if a peer connection goes to normal but another thread still hasn't finished adding queued blocks
@@ -765,6 +776,8 @@ namespace cryptonote
m_core.get_short_chain_history(r.block_ids);
handler_request_blocks_history( r.block_ids ); // change the limit(?), sleep(?)
r.prune = m_sync_pruned_blocks;
+ context.m_last_request_time = boost::posix_time::microsec_clock::universal_time();
+ context.m_expect_response = NOTIFY_RESPONSE_CHAIN_ENTRY::ID;
MLOG_P2P_MESSAGE("-->>NOTIFY_REQUEST_CHAIN: m_block_ids.size()=" << r.block_ids.size() );
post_notify<NOTIFY_REQUEST_CHAIN>(r, context);
MLOG_PEER_STATE("requesting chain");
@@ -1029,6 +1042,7 @@ namespace cryptonote
drop_connection(context, false, false);
return 1;
}
+ context.m_last_request_time = boost::posix_time::microsec_clock::universal_time();
MLOG_P2P_MESSAGE("-->>NOTIFY_RESPONSE_GET_OBJECTS: blocks.size()="
<< rsp.blocks.size() << ", rsp.m_current_blockchain_height=" << rsp.current_blockchain_height
<< ", missed_ids.size()=" << rsp.missed_ids.size());
@@ -1062,6 +1076,14 @@ namespace cryptonote
boost::posix_time::ptime request_time = context.m_last_request_time;
context.m_last_request_time = boost::date_time::not_a_date_time;
+ if (context.m_expect_response != NOTIFY_RESPONSE_GET_OBJECTS::ID)
+ {
+ LOG_ERROR_CCONTEXT("Got NOTIFY_RESPONSE_GET_OBJECTS out of the blue, dropping connection");
+ drop_connection(context, true, false);
+ return 1;
+ }
+ context.m_expect_response = 0;
+
// calculate size of request
size_t size = 0;
size_t blocks_size = 0;
@@ -1107,6 +1129,11 @@ namespace cryptonote
return 1;
}
+ if (arg.current_blockchain_height < context.m_remote_blockchain_height)
+ {
+ MINFO(context << "Claims " << arg.current_blockchain_height << ", claimed " << context.m_remote_blockchain_height << " before");
+ hit_score(context, 1);
+ }
context.m_remote_blockchain_height = arg.current_blockchain_height;
if (context.m_remote_blockchain_height > m_core.get_target_blockchain_height())
m_core.set_target_blockchain_height(context.m_remote_blockchain_height);
@@ -1230,7 +1257,7 @@ namespace cryptonote
const boost::posix_time::time_duration dt = now - request_time;
const float rate = size * 1e6 / (dt.total_microseconds() + 1);
MDEBUG(context << " adding span: " << arg.blocks.size() << " at height " << start_height << ", " << dt.total_microseconds()/1e6 << " seconds, " << (rate/1024) << " kB/s, size now " << (m_block_queue.get_data_size() + blocks_size) / 1048576.f << " MB");
- m_block_queue.add_blocks(start_height, arg.blocks, context.m_connection_id, rate, blocks_size);
+ m_block_queue.add_blocks(start_height, arg.blocks, context.m_connection_id, context.m_remote_address, rate, blocks_size);
const crypto::hash last_block_hash = cryptonote::get_block_hash(b);
context.m_last_known_hash = last_block_hash;
@@ -1331,7 +1358,8 @@ namespace cryptonote
uint64_t start_height;
std::vector<cryptonote::block_complete_entry> blocks;
boost::uuids::uuid span_connection_id;
- if (!m_block_queue.get_next_span(start_height, blocks, span_connection_id))
+ epee::net_utils::network_address span_origin;
+ if (!m_block_queue.get_next_span(start_height, blocks, span_connection_id, span_origin))
{
MDEBUG(context << " no next span found, going back to download");
break;
@@ -1429,6 +1457,7 @@ namespace cryptonote
if (!m_core.prepare_handle_incoming_blocks(blocks, pblocks))
{
LOG_ERROR_CCONTEXT("Failure in prepare_handle_incoming_blocks");
+ drop_connections(span_origin);
return 1;
}
if (!pblocks.empty() && pblocks.size() != blocks.size())
@@ -1468,6 +1497,7 @@ namespace cryptonote
{
if(tvc[i].m_verifivation_failed)
{
+ drop_connections(span_origin);
if (!m_p2p->for_connection(span_connection_id, [&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t f)->bool{
cryptonote::transaction tx;
crypto::hash txid;
@@ -1509,6 +1539,7 @@ namespace cryptonote
if(bvc.m_verifivation_failed)
{
+ drop_connections(span_origin);
if (!m_p2p->for_connection(span_connection_id, [&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t f)->bool{
LOG_PRINT_CCONTEXT_L1("Block verification failed, dropping connection");
drop_connection_with_score(context, bvc.m_bad_pow ? P2P_IP_FAILS_BEFORE_BLOCK : 1, true);
@@ -1528,6 +1559,7 @@ namespace cryptonote
}
if(bvc.m_marked_as_orphaned)
{
+ drop_connections(span_origin);
if (!m_p2p->for_connection(span_connection_id, [&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t f)->bool{
LOG_PRINT_CCONTEXT_L1("Block received at sync phase was marked as orphaned, dropping connection");
drop_connection(context, true, true);
@@ -1666,24 +1698,45 @@ skip:
bool t_cryptonote_protocol_handler<t_core>::kick_idle_peers()
{
MTRACE("Checking for idle peers...");
+ std::vector<std::pair<boost::uuids::uuid, unsigned>> idle_peers;
m_p2p->for_each_connection([&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t support_flags)->bool
{
if (context.m_state == cryptonote_connection_context::state_synchronizing && context.m_last_request_time != boost::date_time::not_a_date_time)
{
const boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();
const boost::posix_time::time_duration dt = now - context.m_last_request_time;
- if (dt.total_microseconds() > IDLE_PEER_KICK_TIME)
+ const auto ms = dt.total_microseconds();
+ if (ms > IDLE_PEER_KICK_TIME || (context.m_expect_response && ms > NON_RESPONSIVE_PEER_KICK_TIME))
{
- MINFO(context << " kicking idle peer, last update " << (dt.total_microseconds() / 1.e6) << " seconds ago");
- LOG_PRINT_CCONTEXT_L2("requesting callback");
- context.m_last_request_time = boost::date_time::not_a_date_time;
- context.m_state = cryptonote_connection_context::state_standby; // we'll go back to adding, then (if we can't), download
- ++context.m_callback_request_count;
- m_p2p->request_callback(context);
+ if (context.m_score-- >= 0)
+ {
+ MINFO(context << " kicking idle peer, last update " << (dt.total_microseconds() / 1.e6) << " seconds ago, expecting " << (int)context.m_expect_response);
+ LOG_PRINT_CCONTEXT_L2("requesting callback");
+ context.m_last_request_time = boost::date_time::not_a_date_time;
+ context.m_expect_response = 0;
+ context.m_state = cryptonote_connection_context::state_standby; // we'll go back to adding, then (if we can't), download
+ ++context.m_callback_request_count;
+ m_p2p->request_callback(context);
+ }
+ else
+ {
+ idle_peers.push_back(std::make_pair(context.m_connection_id, context.m_expect_response == 0 ? 1 : 5));
+ }
}
}
return true;
});
+
+ for (const auto &e: idle_peers)
+ {
+ const auto &uuid = e.first;
+ m_p2p->for_connection(uuid, [&](cryptonote_connection_context& ctx, nodetool::peerid_type peer_id, uint32_t f)->bool{
+ MINFO(ctx << "dropping idle peer with negative score");
+ drop_connection_with_score(ctx, e.second, false);
+ return true;
+ });
+ }
+
return true;
}
//------------------------------------------------------------------------------------------------------------------------
@@ -2125,7 +2178,7 @@ skip:
const uint64_t first_block_height = context.m_last_response_height - context.m_needed_objects.size() + 1;
static const uint64_t bp_fork_height = m_core.get_earliest_ideal_height_for_version(8);
bool sync_pruned_blocks = m_sync_pruned_blocks && first_block_height >= bp_fork_height && m_core.get_blockchain_pruning_seed();
- span = m_block_queue.reserve_span(first_block_height, context.m_last_response_height, count_limit, context.m_connection_id, sync_pruned_blocks, m_core.get_blockchain_pruning_seed(), context.m_pruning_seed, context.m_remote_blockchain_height, context.m_needed_objects);
+ span = m_block_queue.reserve_span(first_block_height, context.m_last_response_height, count_limit, context.m_connection_id, context.m_remote_address, sync_pruned_blocks, m_core.get_blockchain_pruning_seed(), context.m_pruning_seed, context.m_remote_blockchain_height, context.m_needed_objects);
MDEBUG(context << " span from " << first_block_height << ": " << span.first << "/" << span.second);
if (span.second > 0)
{
@@ -2206,6 +2259,7 @@ skip:
}
}
context.m_last_request_time = boost::posix_time::microsec_clock::universal_time();
+ context.m_expect_response = NOTIFY_RESPONSE_GET_OBJECTS::ID;
MLOG_P2P_MESSAGE("-->>NOTIFY_REQUEST_GET_OBJECTS: blocks.size()=" << req.blocks.size()
<< "requested blocks count=" << count << " / " << count_limit << " from " << span.first << ", first hash " << req.blocks.front());
//epee::net_utils::network_throttle_manager::get_global_throttle_inreq().logger_handle_net("log/dr-monero/net/req-all.data", sec, get_avg_block_size());
@@ -2260,8 +2314,8 @@ skip:
uint64_t start_height;
std::vector<cryptonote::block_complete_entry> blocks;
boost::uuids::uuid span_connection_id;
- bool filled = false;
- if (m_block_queue.get_next_span(start_height, blocks, span_connection_id, filled) && filled)
+ epee::net_utils::network_address span_origin;
+ if (m_block_queue.get_next_span(start_height, blocks, span_connection_id, span_origin, true))
{
LOG_DEBUG_CC(context, "No other thread is adding blocks, resuming");
MLOG_PEER_STATE("will try to add blocks next");
@@ -2296,6 +2350,7 @@ skip:
//LOG_PRINT_CCONTEXT_L1("r = " << 200);
context.m_last_request_time = boost::posix_time::microsec_clock::universal_time();
+ context.m_expect_response = NOTIFY_RESPONSE_CHAIN_ENTRY::ID;
MLOG_P2P_MESSAGE("-->>NOTIFY_REQUEST_CHAIN: m_block_ids.size()=" << r.block_ids.size() << ", start_from_current_chain " << start_from_current_chain);
post_notify<NOTIFY_REQUEST_CHAIN>(r, context);
MLOG_PEER_STATE("requesting chain");
@@ -2321,7 +2376,7 @@ skip:
}
else
{
- MINFO(context << " we've reached this peer's blockchain height");
+ MINFO(context << " we've reached this peer's blockchain height (theirs " << context.m_remote_blockchain_height << ", our target " << m_core.get_target_blockchain_height());
}
}
return true;
@@ -2418,6 +2473,14 @@ skip:
<< ", m_start_height=" << arg.start_height << ", m_total_height=" << arg.total_height);
MLOG_PEER_STATE("received chain");
+ if (context.m_expect_response != NOTIFY_RESPONSE_CHAIN_ENTRY::ID)
+ {
+ LOG_ERROR_CCONTEXT("Got NOTIFY_RESPONSE_CHAIN_ENTRY out of the blue, dropping connection");
+ drop_connection(context, true, false);
+ return 1;
+ }
+ context.m_expect_response = 0;
+
context.m_last_request_time = boost::date_time::not_a_date_time;
m_sync_download_chain_size += arg.m_block_ids.size() * sizeof(crypto::hash);
@@ -2428,7 +2491,7 @@ skip:
drop_connection(context, true, false);
return 1;
}
- if (arg.total_height < arg.m_block_ids.size() || arg.start_height > arg.total_height - arg.m_block_ids.size())
+ if (arg.total_height < arg.m_block_ids.size() || arg.start_height > arg.total_height - arg.m_block_ids.size() || arg.start_height >= m_core.get_current_blockchain_height())
{
LOG_ERROR_CCONTEXT("sent invalid start/nblocks/height, dropping connection");
drop_connection(context, true, false);
@@ -2448,6 +2511,11 @@ skip:
drop_connection(context, false, false);
return 1;
}
+ if (arg.total_height < context.m_remote_blockchain_height)
+ {
+ MINFO(context << "Claims " << arg.total_height << ", claimed " << context.m_remote_blockchain_height << " before");
+ hit_score(context, 1);
+ }
context.m_remote_blockchain_height = arg.total_height;
context.m_last_response_height = arg.start_height + arg.m_block_ids.size()-1;
if(context.m_last_response_height > context.m_remote_blockchain_height)
@@ -2469,8 +2537,15 @@ skip:
context.m_needed_objects.clear();
uint64_t added = 0;
+ std::unordered_set<crypto::hash> blocks_found;
for (size_t i = 0; i < arg.m_block_ids.size(); ++i)
{
+ if (!blocks_found.insert(arg.m_block_ids[i]).second)
+ {
+ LOG_ERROR_CCONTEXT("Duplicate blocks in chain entry response, dropping connection");
+ drop_connection(context, true, false);
+ return 1;
+ }
const uint64_t block_weight = arg.m_block_weights.empty() ? 0 : arg.m_block_weights[i];
context.m_needed_objects.push_back(std::make_pair(arg.m_block_ids[i], block_weight));
if (++added == n_use_blocks)
@@ -2564,6 +2639,19 @@ skip:
}
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
+ void t_cryptonote_protocol_handler<t_core>::hit_score(cryptonote_connection_context &context, int32_t score)
+ {
+ if (score <= 0)
+ {
+ MERROR("Negative score hit");
+ return;
+ }
+ context.m_score -= score;
+ if (context.m_score <= DROP_PEERS_ON_SCORE)
+ drop_connection_with_score(context, 5, false);
+ }
+ //------------------------------------------------------------------------------------------------------------------------
+ template<class t_core>
std::string t_cryptonote_protocol_handler<t_core>::get_peers_overview() const
{
std::stringstream ss;
@@ -2659,6 +2747,29 @@ skip:
}
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
+ void t_cryptonote_protocol_handler<t_core>::drop_connections(const epee::net_utils::network_address address)
+ {
+ MWARNING("dropping connections to " << address.str());
+
+ m_p2p->add_host_fail(address, 5);
+
+ std::vector<boost::uuids::uuid> drop;
+ m_p2p->for_each_connection([&](const connection_context& cntxt, nodetool::peerid_type peer_id, uint32_t support_flags) {
+ if (address.is_same_host(cntxt.m_remote_address))
+ drop.push_back(cntxt.m_connection_id);
+ return true;
+ });
+ for (const boost::uuids::uuid &id: drop)
+ {
+ m_block_queue.flush_spans(id, true);
+ m_p2p->for_connection(id, [&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t f)->bool{
+ drop_connection(context, true, false);
+ return true;
+ });
+ }
+ }
+ //------------------------------------------------------------------------------------------------------------------------
+ template<class t_core>
void t_cryptonote_protocol_handler<t_core>::on_connection_close(cryptonote_connection_context &context)
{
uint64_t target = 0;
diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h
index 87fec9994..f13b36a82 100644
--- a/src/p2p/net_node.h
+++ b/src/p2p/net_node.h
@@ -149,7 +149,7 @@ namespace nodetool
{
config_t()
: m_net_config(),
- m_peer_id(crypto::rand<uint64_t>()),
+ m_peer_id(1),
m_support_flags(0)
{}
@@ -287,7 +287,7 @@ namespace nodetool
uint32_t get_max_out_public_peers() const;
void change_max_in_public_peers(size_t count);
uint32_t get_max_in_public_peers() const;
- virtual bool block_host(const epee::net_utils::network_address &adress, time_t seconds = P2P_IP_BLOCKTIME);
+ virtual bool block_host(epee::net_utils::network_address address, time_t seconds = P2P_IP_BLOCKTIME);
virtual bool unblock_host(const epee::net_utils::network_address &address);
virtual bool block_subnet(const epee::net_utils::ipv4_network_subnet &subnet, time_t seconds = P2P_IP_BLOCKTIME);
virtual bool unblock_subnet(const epee::net_utils::ipv4_network_subnet &subnet);
diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl
index c71dfc2de..65db2615c 100644
--- a/src/p2p/net_node.inl
+++ b/src/p2p/net_node.inl
@@ -139,7 +139,9 @@ namespace nodetool
if (storage)
m_peerlist_storage = std::move(*storage);
- m_network_zones[epee::net_utils::zone::public_].m_config.m_support_flags = P2P_SUPPORT_FLAGS;
+ network_zone& public_zone = m_network_zones[epee::net_utils::zone::public_];
+ public_zone.m_config.m_support_flags = P2P_SUPPORT_FLAGS;
+ public_zone.m_config.m_peer_id = crypto::rand<uint64_t>();
m_first_connection_maker_call = true;
CATCH_ENTRY_L0("node_server::init_config", false);
@@ -224,7 +226,7 @@ namespace nodetool
}
//-----------------------------------------------------------------------------------
template<class t_payload_net_handler>
- bool node_server<t_payload_net_handler>::block_host(const epee::net_utils::network_address &addr, time_t seconds)
+ bool node_server<t_payload_net_handler>::block_host(epee::net_utils::network_address addr, time_t seconds)
{
if(!addr.is_blockable())
return false;
@@ -237,7 +239,8 @@ namespace nodetool
limit = std::numeric_limits<time_t>::max();
else
limit = now + seconds;
- m_blocked_hosts[addr.host_str()] = limit;
+ const std::string host_str = addr.host_str();
+ m_blocked_hosts[host_str] = limit;
// drop any connection to that address. This should only have to look into
// the zone related to the connection, but really make sure everything is
@@ -253,17 +256,18 @@ namespace nodetool
}
return true;
});
- for (const auto &c: conns)
- zone.second.m_net_server.get_config_object().close(c);
-
- conns.clear();
peerlist_entry pe{};
pe.adr = addr;
zone.second.m_peerlist.remove_from_peer_white(pe);
+
+ for (const auto &c: conns)
+ zone.second.m_net_server.get_config_object().close(c);
+
+ conns.clear();
}
- MCLOG_CYAN(el::Level::Info, "global", "Host " << addr.host_str() << " blocked.");
+ MCLOG_CYAN(el::Level::Info, "global", "Host " << host_str << " blocked.");
return true;
}
//-----------------------------------------------------------------------------------
@@ -1135,11 +1139,12 @@ namespace nodetool
pi = context.peer_id = rsp.node_data.peer_id;
context.m_rpc_port = rsp.node_data.rpc_port;
context.m_rpc_credits_per_hash = rsp.node_data.rpc_credits_per_hash;
- network_zone& zone = m_network_zones.at(context.m_remote_address.get_zone());
+ const auto azone = context.m_remote_address.get_zone();
+ network_zone& zone = m_network_zones.at(azone);
zone.m_peerlist.set_peer_just_seen(rsp.node_data.peer_id, context.m_remote_address, context.m_pruning_seed, context.m_rpc_port, context.m_rpc_credits_per_hash);
// move
- if(rsp.node_data.peer_id == zone.m_config.m_peer_id)
+ if(azone == epee::net_utils::zone::public_ && rsp.node_data.peer_id == zone.m_config.m_peer_id)
{
LOG_DEBUG_CC(context, "Connection to self detected, dropping connection");
hsh_result = false;
@@ -1231,50 +1236,51 @@ namespace nodetool
template<class t_payload_net_handler>
bool node_server<t_payload_net_handler>::is_peer_used(const peerlist_entry& peer)
{
- for(const auto& zone : m_network_zones)
- if(zone.second.m_config.m_peer_id == peer.id)
- return true;//dont make connections to ourself
+ const auto zone = peer.adr.get_zone();
+ const auto server = m_network_zones.find(zone);
+ if (server == m_network_zones.end())
+ return false;
+
+ const bool is_public = (zone == epee::net_utils::zone::public_);
+ if(is_public && server->second.m_config.m_peer_id == peer.id)
+ return true;//dont make connections to ourself
bool used = false;
- for(auto& zone : m_network_zones)
+ server->second.m_net_server.get_config_object().foreach_connection([&, is_public](const p2p_connection_context& cntxt)
{
- zone.second.m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
+ if((is_public && cntxt.peer_id == peer.id) || (!cntxt.m_is_income && peer.adr == cntxt.m_remote_address))
{
- if(cntxt.peer_id == peer.id || (!cntxt.m_is_income && peer.adr == cntxt.m_remote_address))
- {
- used = true;
- return false;//stop enumerating
- }
- return true;
- });
-
- if(used)
- return true;
- }
- return false;
+ used = true;
+ return false;//stop enumerating
+ }
+ return true;
+ });
+ return used;
}
//-----------------------------------------------------------------------------------
template<class t_payload_net_handler>
bool node_server<t_payload_net_handler>::is_peer_used(const anchor_peerlist_entry& peer)
{
- for(auto& zone : m_network_zones) {
- if(zone.second.m_config.m_peer_id == peer.id) {
- return true;//dont make connections to ourself
- }
- bool used = false;
- zone.second.m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
+ const auto zone = peer.adr.get_zone();
+ const auto server = m_network_zones.find(zone);
+ if (server == m_network_zones.end())
+ return false;
+
+ const bool is_public = (zone == epee::net_utils::zone::public_);
+ if(is_public && server->second.m_config.m_peer_id == peer.id)
+ return true;//dont make connections to ourself
+
+ bool used = false;
+ server->second.m_net_server.get_config_object().foreach_connection([&, is_public](const p2p_connection_context& cntxt)
+ {
+ if((is_public && cntxt.peer_id == peer.id) || (!cntxt.m_is_income && peer.adr == cntxt.m_remote_address))
{
- if(cntxt.peer_id == peer.id || (!cntxt.m_is_income && peer.adr == cntxt.m_remote_address))
- {
- used = true;
- return false;//stop enumerating
- }
- return true;
- });
- if (used)
- return true;
- }
- return false;
+ used = true;
+ return false;//stop enumerating
+ }
+ return true;
+ });
+ return used;
}
//-----------------------------------------------------------------------------------
template<class t_payload_net_handler>
@@ -1320,6 +1326,9 @@ namespace nodetool
if (zone.m_connect == nullptr) // outgoing connections in zone not possible
return false;
+ if (zone.m_our_address == na)
+ return false;
+
if (zone.m_current_number_of_out_peers == zone.m_config.m_net_config.max_out_connection_count) // out peers limit
{
return false;
@@ -1647,6 +1656,9 @@ namespace nodetool
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(zone.m_our_address == pe.adr)
+ continue;
+
if(is_peer_used(pe)) {
_note("Peer is used");
continue;
@@ -2060,6 +2072,11 @@ namespace nodetool
template<class t_payload_net_handler>
bool node_server<t_payload_net_handler>::handle_remote_peerlist(const std::vector<peerlist_entry>& peerlist, const epee::net_utils::connection_context_base& context)
{
+ if (peerlist.size() > P2P_MAX_PEERS_IN_HANDSHAKE)
+ {
+ MWARNING(context << "peer sent " << peerlist.size() << " peers, considered spamming");
+ return false;
+ }
std::vector<peerlist_entry> peerlist_ = peerlist;
if(!sanitize_peerlist(peerlist_))
return false;
@@ -2420,11 +2437,12 @@ namespace nodetool
return 1;
}
- network_zone& zone = m_network_zones.at(context.m_remote_address.get_zone());
+ const auto azone = context.m_remote_address.get_zone();
+ network_zone& zone = m_network_zones.at(azone);
// test only the remote end's zone, otherwise an attacker could connect to you on clearnet
// and pass in a tor connection's peer id, and deduce the two are the same if you reject it
- if(arg.node_data.peer_id == zone.m_config.m_peer_id)
+ if(azone == epee::net_utils::zone::public_ && arg.node_data.peer_id == zone.m_config.m_peer_id)
{
LOG_DEBUG_CC(context, "Connection to self detected, dropping connection");
drop_connection(context);
diff --git a/src/p2p/net_node_common.h b/src/p2p/net_node_common.h
index 2ace5987f..f1490a0db 100644
--- a/src/p2p/net_node_common.h
+++ b/src/p2p/net_node_common.h
@@ -58,7 +58,7 @@ namespace nodetool
virtual uint64_t get_public_connections_count()=0;
virtual void for_each_connection(std::function<bool(t_connection_context&, peerid_type, uint32_t)> f)=0;
virtual bool for_connection(const boost::uuids::uuid&, std::function<bool(t_connection_context&, peerid_type, uint32_t)> f)=0;
- virtual bool block_host(const epee::net_utils::network_address &address, time_t seconds = 0)=0;
+ virtual bool block_host(epee::net_utils::network_address address, time_t seconds = 0)=0;
virtual bool unblock_host(const epee::net_utils::network_address &address)=0;
virtual std::map<std::string, time_t> get_blocked_hosts()=0;
virtual std::map<epee::net_utils::ipv4_network_subnet, time_t> get_blocked_subnets()=0;
@@ -108,7 +108,7 @@ namespace nodetool
{
return false;
}
- virtual bool block_host(const epee::net_utils::network_address &address, time_t seconds)
+ virtual bool block_host(epee::net_utils::network_address address, time_t seconds)
{
return true;
}
diff --git a/src/p2p/net_peerlist.cpp b/src/p2p/net_peerlist.cpp
index ce5c67fe5..42ab9727d 100644
--- a/src/p2p/net_peerlist.cpp
+++ b/src/p2p/net_peerlist.cpp
@@ -288,6 +288,19 @@ namespace nodetool
copy_peers(peers.gray, m_peers_gray.get<by_addr>());
copy_peers(peers.anchor, m_peers_anchor.get<by_addr>());
}
+
+ void peerlist_manager::evict_host_from_white_peerlist(const peerlist_entry& pr)
+ {
+ peers_indexed::index<by_time>::type& sorted_index=m_peers_white.get<by_time>();
+ auto i = sorted_index.begin();
+ while (i != sorted_index.end())
+ {
+ if (i->adr.is_same_host(pr.adr))
+ i = sorted_index.erase(i);
+ else
+ ++i;
+ }
+ }
}
BOOST_CLASS_VERSION(nodetool::peerlist_types, nodetool::CURRENT_PEERLIST_STORAGE_ARCHIVE_VER);
diff --git a/src/p2p/net_peerlist.h b/src/p2p/net_peerlist.h
index 992462d0b..c794b0f3b 100644
--- a/src/p2p/net_peerlist.h
+++ b/src/p2p/net_peerlist.h
@@ -109,6 +109,7 @@ namespace nodetool
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);
+ void evict_host_from_white_peerlist(const peerlist_entry& pr);
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);
@@ -345,6 +346,7 @@ namespace nodetool
if(by_addr_it_wt == m_peers_white.get<by_addr>().end())
{
//put new record into white list
+ evict_host_from_white_peerlist(ple);
m_peers_white.insert(ple);
trim_white_peerlist();
}else
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index f028fe06f..f7d5bf03c 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -2913,11 +2913,7 @@ namespace cryptonote
block_queue.foreach([&](const cryptonote::block_queue::span &span) {
const std::string span_connection_id = epee::string_tools::pod_to_hex(span.connection_id);
uint32_t speed = (uint32_t)(100.0f * block_queue.get_speed(span.connection_id) + 0.5f);
- std::string address = "";
- for (const auto &c: m_p2p.get_payload_object().get_connections())
- if (c.connection_id == span_connection_id)
- address = c.address;
- res.spans.push_back({span.start_block_height, span.nblocks, span_connection_id, (uint32_t)(span.rate + 0.5f), speed, span.size, address});
+ res.spans.push_back({span.start_block_height, span.nblocks, span_connection_id, (uint32_t)(span.rate + 0.5f), speed, span.size, span.origin.str()});
return true;
});
res.overview = block_queue.get_overview(res.height);
diff --git a/src/version.cpp.in b/src/version.cpp.in
index 6658cb3b1..00b5c5643 100644
--- a/src/version.cpp.in
+++ b/src/version.cpp.in
@@ -1,5 +1,5 @@
#define DEF_MONERO_VERSION_TAG "@VERSIONTAG@"
-#define DEF_MONERO_VERSION "0.17.1.5"
+#define DEF_MONERO_VERSION "0.17.1.6"
#define DEF_MONERO_RELEASE_NAME "Oxygen Orion"
#define DEF_MONERO_VERSION_FULL DEF_MONERO_VERSION "-" DEF_MONERO_VERSION_TAG
#define DEF_MONERO_VERSION_IS_RELEASE @VERSION_IS_RELEASE@
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 65411e392..299e427ce 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -2961,7 +2961,8 @@ void wallet2::update_pool_state(std::vector<std::tuple<cryptonote::transaction,
MTRACE("update_pool_state got pool");
// remove any pending tx that's not in the pool
- constexpr const std::chrono::seconds tx_propagation_timeout{CRYPTONOTE_DANDELIONPP_EMBARGO_AVERAGE * 3 / 2};
+ // TODO: set tx_propagation_timeout to CRYPTONOTE_DANDELIONPP_EMBARGO_AVERAGE * 3 / 2 after v15 hardfork
+ constexpr const std::chrono::seconds tx_propagation_timeout{500};
const auto now = std::chrono::system_clock::now();
std::unordered_map<crypto::hash, wallet2::unconfirmed_transfer_details>::iterator it = m_unconfirmed_txs.begin();
while (it != m_unconfirmed_txs.end())