P2P network stability improvement
This commit is contained in:
parent
f697d93978
commit
b3a91f67d7
6 changed files with 87 additions and 50 deletions
|
@ -153,7 +153,8 @@ const CheckpointData CHECKPOINTS[] = {
|
|||
{713000, "a03f836c4a19f907cd6cac095eb6f56f5279ca2d1303fb7f826750dcb9025495"},
|
||||
{750300, "5117631dbeb5c14748a91127a515ecbf13f6849e14fda7ee03cd55da41f1710c"},
|
||||
{780000, "8dd55a9bae429e3685b90317281e633917023d3512eb7f37372209d1a5fc1070"},
|
||||
{785500, "de1a487d70964d25ed6f7de196866f357a293e867ee81313e7fd0352d0126bdd"}
|
||||
{785500, "de1a487d70964d25ed6f7de196866f357a293e867ee81313e7fd0352d0126bdd"},
|
||||
{789000, "acef490bbccce3b7b7ae8554a414f55413fbf4ca1472c6359b126a4439bd9f01"}
|
||||
};
|
||||
} // CryptoNote
|
||||
|
||||
|
|
|
@ -51,8 +51,8 @@ namespace CryptoNote
|
|||
|
||||
cryptonote_protocol_handler(const Currency& currency, System::Dispatcher& dispatcher, ICore& rcore, i_p2p_endpoint* p_net_layout, Logging::ILogger& log);
|
||||
|
||||
virtual bool addObserver(ICryptonoteProtocolObserver* observer);
|
||||
virtual bool removeObserver(ICryptonoteProtocolObserver* observer);
|
||||
virtual bool addObserver(ICryptonoteProtocolObserver* observer) override;
|
||||
virtual bool removeObserver(ICryptonoteProtocolObserver* observer) override;
|
||||
|
||||
void set_p2p_endpoint(i_p2p_endpoint* p2p);
|
||||
// ICore& get_core() { return m_core; }
|
||||
|
@ -69,8 +69,8 @@ namespace CryptoNote
|
|||
bool get_payload_sync_data(CORE_SYNC_DATA& hshd);
|
||||
bool process_payload_sync_data(const CORE_SYNC_DATA& hshd, cryptonote_connection_context& context, bool is_inital);
|
||||
int handleCommand(bool is_notify, int command, const std::string& in_buff, std::string& buff_out, cryptonote_connection_context& context, bool& handled);
|
||||
virtual size_t getPeerCount() const;
|
||||
virtual uint64_t getObservedHeight() const;
|
||||
virtual size_t getPeerCount() const override;
|
||||
virtual uint64_t getObservedHeight() const override;
|
||||
void requestMissingPoolTransactions(const cryptonote_connection_context& context);
|
||||
|
||||
private:
|
||||
|
|
|
@ -66,7 +66,9 @@ std::string LevinProtocol::sendBuf(uint32_t command, const std::string& out, boo
|
|||
std::string response;
|
||||
|
||||
if (readResponse) {
|
||||
m_conn.read(reinterpret_cast<uint8_t*>(&head), sizeof(head));
|
||||
if (!readStrict(reinterpret_cast<uint8_t*>(&head), sizeof(head))) {
|
||||
throw std::runtime_error("Levin::sendBuf, failed to read header, peer closed connection");
|
||||
}
|
||||
|
||||
if (head.m_signature != LEVIN_SIGNATURE) {
|
||||
throw std::runtime_error("Levin signature mismatch");
|
||||
|
@ -79,7 +81,9 @@ std::string LevinProtocol::sendBuf(uint32_t command, const std::string& out, boo
|
|||
response.resize(head.m_cb);
|
||||
|
||||
if (response.size()) {
|
||||
readStrict(&response[0], head.m_cb);
|
||||
if (!readStrict(&response[0], head.m_cb)) {
|
||||
throw std::runtime_error("Levin::sendBuf, failed to read body, peer closed connection");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "net_node.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <exception>
|
||||
#include <fstream>
|
||||
|
||||
#include <boost/archive/binary_oarchive.hpp>
|
||||
|
@ -435,11 +436,7 @@ namespace CryptoNote
|
|||
m_idleTimer.stop();
|
||||
m_timedSyncTimer.stop();
|
||||
|
||||
logger(INFO) << "Stopping " << m_connections.size() + m_raw_connections.size() << " connections";
|
||||
|
||||
for (auto& conn : m_raw_connections) {
|
||||
conn.second.connection.stop();
|
||||
}
|
||||
logger(INFO) << "Stopping " << m_connections.size() << " connections";
|
||||
|
||||
for (auto& conn : m_connections) {
|
||||
conn.second.connection.stop();
|
||||
|
@ -639,35 +636,38 @@ namespace CryptoNote
|
|||
|
||||
try {
|
||||
System::TcpConnector connector(m_dispatcher);
|
||||
|
||||
System::Event timeoutEvent(m_dispatcher);
|
||||
System::Timer timeoutTimer(m_dispatcher);
|
||||
|
||||
m_dispatcher.spawn([&](){
|
||||
System::Event connectorTimeoutEvent(m_dispatcher);
|
||||
System::Timer connectorTimeoutTimer(m_dispatcher);
|
||||
|
||||
m_dispatcher.spawn([&]() {
|
||||
try {
|
||||
timeoutTimer.sleep(std::chrono::milliseconds(m_config.m_net_config.connection_timeout));
|
||||
connectorTimeoutTimer.sleep(std::chrono::milliseconds(m_config.m_net_config.connection_timeout));
|
||||
connector.stop();
|
||||
} catch (std::exception&) {}
|
||||
timeoutEvent.set();
|
||||
} catch (std::exception&) {
|
||||
}
|
||||
|
||||
connectorTimeoutEvent.set();
|
||||
});
|
||||
|
||||
System::TcpConnection connection;
|
||||
|
||||
try {
|
||||
connection = connector.connect(System::Ipv4Address(Common::ipAddressToString(na.ip)), static_cast<uint16_t>(na.port));
|
||||
connection =
|
||||
connector.connect(System::Ipv4Address(Common::ipAddressToString(na.ip)), static_cast<uint16_t>(na.port));
|
||||
} catch (System::InterruptedException&) {
|
||||
timeoutEvent.wait();
|
||||
connectorTimeoutEvent.wait();
|
||||
return false;
|
||||
} catch (std::exception&) {
|
||||
timeoutTimer.stop();
|
||||
timeoutEvent.wait();
|
||||
} catch (std::exception& e) {
|
||||
connectorTimeoutTimer.stop();
|
||||
connectorTimeoutEvent.wait();
|
||||
throw;
|
||||
}
|
||||
|
||||
p2p_connection_context ctx(m_dispatcher, std::move(connection));
|
||||
|
||||
timeoutTimer.stop();
|
||||
timeoutEvent.wait();
|
||||
connectorTimeoutTimer.stop();
|
||||
connectorTimeoutEvent.wait();
|
||||
|
||||
// p2p_connection_context ctx(m_dispatcher, std::move(connector.connect()));
|
||||
|
||||
|
@ -677,39 +677,68 @@ namespace CryptoNote
|
|||
ctx.m_is_income = false;
|
||||
ctx.m_started = time(nullptr);
|
||||
|
||||
auto raw = m_raw_connections.emplace(ctx.m_connection_id, std::move(ctx)).first;
|
||||
try {
|
||||
CryptoNote::LevinProtocol proto(raw->second.connection);
|
||||
|
||||
if (!handshake(proto, raw->second, just_take_peerlist)) {
|
||||
logger(WARNING) << "Failed to HANDSHAKE with peer " << na;
|
||||
m_raw_connections.erase(raw);
|
||||
return false;
|
||||
System::Event handshakeTimeoutFinishedEvent(m_dispatcher);
|
||||
System::Event handshakeFinishedEvent(m_dispatcher);
|
||||
System::Timer handshakeTimeoutTimer(m_dispatcher);
|
||||
m_dispatcher.spawn([&] {
|
||||
try {
|
||||
handshakeTimeoutTimer.sleep(std::chrono::milliseconds(m_config.m_net_config.connection_timeout));
|
||||
ctx.connection.stop();
|
||||
} catch (std::exception& e) {
|
||||
}
|
||||
} catch (...) {
|
||||
m_raw_connections.erase(raw);
|
||||
throw;
|
||||
|
||||
handshakeTimeoutFinishedEvent.set();
|
||||
});
|
||||
|
||||
CryptoNote::LevinProtocol proto(ctx.connection);
|
||||
bool error = false;
|
||||
std::exception_ptr exceptionHolder;
|
||||
m_dispatcher.spawn([&] {
|
||||
try {
|
||||
if (!handshake(proto, ctx, just_take_peerlist)) {
|
||||
logger(WARNING) << "Failed to HANDSHAKE with peer " << na;
|
||||
error = true;
|
||||
}
|
||||
|
||||
} catch (System::InterruptedException&) {
|
||||
error = true;
|
||||
handshakeFinishedEvent.set();
|
||||
return;
|
||||
} catch (...) {
|
||||
exceptionHolder = std::current_exception();
|
||||
}
|
||||
|
||||
handshakeTimeoutTimer.stop();
|
||||
handshakeFinishedEvent.set();
|
||||
});
|
||||
|
||||
handshakeFinishedEvent.wait();
|
||||
handshakeTimeoutFinishedEvent.wait();
|
||||
if (error) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (exceptionHolder != nullptr) {
|
||||
std::rethrow_exception(exceptionHolder);
|
||||
}
|
||||
|
||||
if (just_take_peerlist) {
|
||||
logger(Logging::DEBUGGING, Logging::BRIGHT_GREEN) << raw->second << "CONNECTION HANDSHAKED OK AND CLOSED.";
|
||||
m_raw_connections.erase(raw);
|
||||
logger(Logging::DEBUGGING, Logging::BRIGHT_GREEN) << ctx << "CONNECTION HANDSHAKED OK AND CLOSED.";
|
||||
return true;
|
||||
}
|
||||
|
||||
peerlist_entry pe_local = boost::value_initialized<peerlist_entry>();
|
||||
pe_local.adr = na;
|
||||
pe_local.id = raw->second.peer_id;
|
||||
pe_local.id = ctx.peer_id;
|
||||
time(&pe_local.last_seen);
|
||||
m_peerlist.append_with_peer_white(pe_local);
|
||||
|
||||
if (m_stop) {
|
||||
m_raw_connections.erase(raw);
|
||||
throw System::InterruptedException();
|
||||
}
|
||||
|
||||
auto iter = m_connections.emplace(raw->first, std::move(raw->second)).first;
|
||||
m_raw_connections.erase(raw);
|
||||
auto key = ctx.m_connection_id;
|
||||
auto iter = m_connections.emplace(key, std::move(ctx)).first;
|
||||
const boost::uuids::uuid& connectionId = iter->first;
|
||||
p2p_connection_context& connectionContext = iter->second;
|
||||
|
||||
|
@ -784,7 +813,7 @@ namespace CryptoNote
|
|||
size_t try_count = 0;
|
||||
size_t current_index = crypto::rand<size_t>()%m_seed_nodes.size();
|
||||
|
||||
while(true) {
|
||||
while(true) {
|
||||
if(try_to_connect_and_handshake_with_new_peer(m_seed_nodes[current_index], true))
|
||||
break;
|
||||
|
||||
|
@ -855,8 +884,12 @@ namespace CryptoNote
|
|||
|
||||
//-----------------------------------------------------------------------------------
|
||||
bool node_server::idle_worker() {
|
||||
m_connections_maker_interval.call(std::bind(&node_server::connections_maker, this));
|
||||
m_peerlist_store_interval.call(std::bind(&node_server::store_config, this));
|
||||
try {
|
||||
m_connections_maker_interval.call(std::bind(&node_server::connections_maker, this));
|
||||
m_peerlist_store_interval.call(std::bind(&node_server::store_config, this));
|
||||
} catch (std::exception& e) {
|
||||
logger(DEBUGGING) << "exception in idle_worker: " << e.what();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ namespace CryptoNote
|
|||
// debug functions
|
||||
bool log_peerlist();
|
||||
bool log_connections();
|
||||
virtual uint64_t get_connections_count();
|
||||
virtual uint64_t get_connections_count() override;
|
||||
size_t get_outgoing_connections_count();
|
||||
|
||||
CryptoNote::peerlist_manager& get_peerlist_manager() { return m_peerlist; }
|
||||
|
@ -171,7 +171,6 @@ namespace CryptoNote
|
|||
|
||||
typedef std::unordered_map<boost::uuids::uuid, p2p_connection_context, boost::hash<boost::uuids::uuid>> ConnectionContainer;
|
||||
typedef ConnectionContainer::iterator ConnectionIterator;
|
||||
ConnectionContainer m_raw_connections;
|
||||
ConnectionContainer m_connections;
|
||||
|
||||
void acceptLoop();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define BUILD_COMMIT_ID "@VERSION@"
|
||||
#define PROJECT_VERSION "1.0.5"
|
||||
#define PROJECT_VERSION_BUILD_NO "503"
|
||||
#define PROJECT_VERSION "1.0.5.1"
|
||||
#define PROJECT_VERSION_BUILD_NO "505"
|
||||
#define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO "(" BUILD_COMMIT_ID ")"
|
||||
|
|
Loading…
Reference in a new issue