From bb289379eb8378fa0c741ceb028908616db890ae Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Fri, 9 Jun 2023 15:12:52 -0500 Subject: [PATCH 1/4] GH-1240 Prevent infinite loop in net_plugin by not sending back a handshake for a catch_up notice if nothing new to report. --- plugins/net_plugin/net_plugin.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index 33985d98ee..397964d3f4 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -1935,7 +1935,12 @@ namespace eosio { verify_catchup( c, msg.known_blocks.pending, id ); } else { // we already have the block, so update peer with our view of the world - c->send_handshake(); + auto chain_info = my_impl->get_chain_info(); + std::unique_lock g_conn( c->conn_mtx ); + if (chain_info.head_id != c->last_handshake_sent.head_id) { // no need to send handshake if nothing new to report + g_conn.unlock(); + c->send_handshake(); + } } } } else if (msg.known_blocks.mode == last_irr_catch_up) { From 2409db22d83990731ddffe5ebae0debc42981c3a Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Fri, 9 Jun 2023 11:37:57 -0500 Subject: [PATCH 2/4] GH-1027 catch_up message with head was being ignored. This was likely not noticed before because handshake would provide it eventually. --- plugins/net_plugin/net_plugin.cpp | 7 +++---- plugins/producer_plugin/producer_plugin.cpp | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index 397964d3f4..b2cd87bf33 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -1966,6 +1966,7 @@ namespace eosio { c->close(); } else { g.unlock(); + peer_dlog(c, "rejected block ${bn}, sending handshake", ("bn", blk_num)); c->send_handshake(); } } @@ -3061,15 +3062,13 @@ namespace eosio { switch (msg.known_trx.mode) { case none: break; - case last_irr_catch_up: { + case last_irr_catch_up: + case catch_up : { std::unique_lock g_conn( conn_mtx ); last_handshake_recv.head_num = msg.known_blocks.pending; g_conn.unlock(); break; } - case catch_up : { - break; - } case normal: { my_impl->dispatcher->recv_notice( shared_from_this(), msg, false ); } diff --git a/plugins/producer_plugin/producer_plugin.cpp b/plugins/producer_plugin/producer_plugin.cpp index d9121e11de..506b03b9ad 100644 --- a/plugins/producer_plugin/producer_plugin.cpp +++ b/plugins/producer_plugin/producer_plugin.cpp @@ -605,7 +605,7 @@ class producer_plugin_impl : public std::enable_shared_from_this().publish( priority::medium, block ); throw; }; From affbbd087fa1c4beefb7e6bbd942b7f5168e320a Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Sat, 10 Jun 2023 08:46:45 -0500 Subject: [PATCH 3/4] GH-1240 get_time is supposed to be nanoseconds --- plugins/net_plugin/net_plugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index b2cd87bf33..9e3e7b340e 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -743,7 +743,7 @@ namespace eosio { * day routine and converts to a (at least) 64 bit integer. */ static tstamp get_time() { - return std::chrono::system_clock::now().time_since_epoch().count(); + return std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); } /** @} */ From 8ffb1b44123b6c0989f75c5c444e75e3a8a0c640 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Sat, 10 Jun 2023 10:06:09 -0500 Subject: [PATCH 4/4] GH-1240 Better handling of close when not syncing --- plugins/net_plugin/net_plugin.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index 9e3e7b340e..ca98f680ed 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -1590,8 +1590,8 @@ namespace eosio { } ); sync_known_lib_num = highest_lib_num; - // if closing the connection we are currently syncing from or not syncing, then reset our last requested and next expected. - if( !sync_source || c == sync_source ) { + // if closing the connection we are currently syncing from then request from a diff peer + if( c == sync_source ) { reset_last_requested_num(g); // if starting to sync need to always start from lib as we might be on our own fork uint32_t lib_num = my_impl->get_chain_lib_num(); @@ -1958,7 +1958,10 @@ namespace eosio { void sync_manager::rejected_block( const connection_ptr& c, uint32_t blk_num ) { c->block_status_monitor_.rejected(); std::unique_lock g( sync_mtx ); - reset_last_requested_num(g); + sync_last_requested_num = 0; + if (blk_num < sync_next_expected_num) { + sync_next_expected_num = my_impl->get_chain_lib_num(); + } if( c->block_status_monitor_.max_events_violated()) { peer_wlog( c, "block ${bn} not accepted, closing connection", ("bn", blk_num) ); sync_source.reset();