Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.1] net_plugin improve block latency calculation #676

Merged
merged 3 commits into from
Feb 2, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 20 additions & 16 deletions plugins/net_plugin/net_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <boost/asio/steady_timer.hpp>

#include <atomic>
#include <cmath>
#include <shared_mutex>

using namespace eosio::chain::plugin_interface;
Expand Down Expand Up @@ -1776,7 +1777,6 @@ namespace eosio {
if( c->is_transactions_only_connection() ) return;

uint32_t lib_num = 0;
uint32_t peer_lib = msg.last_irreversible_block_num;
uint32_t head = 0;
block_id_type head_id;
std::tie( lib_num, std::ignore, head,
Expand All @@ -1790,10 +1790,10 @@ namespace eosio {
peer_wlog(c, "Peer sent a handshake with a timestamp skewed by at least ${t}ms", ("t", network_latency_ns/1000000));
network_latency_ns = 0;
}
// number of blocks syncing node is behind from a peer node
uint32_t nblk_behind_by_net_latency = static_cast<uint32_t>(network_latency_ns / block_interval_ns);
// 2x for time it takes for message to reach back to peer node, +1 to compensate for integer division truncation
uint32_t nblk_combined_latency = 2 * nblk_behind_by_net_latency + 1;
// number of blocks syncing node is behind from a peer node, round up
uint32_t nblk_behind_by_net_latency = std::lround( static_cast<double>(network_latency_ns) / static_cast<double>(block_interval_ns) );
// 2x for time it takes for message to reach back to peer node
uint32_t nblk_combined_latency = 2 * nblk_behind_by_net_latency;
linh2931 marked this conversation as resolved.
Show resolved Hide resolved
// message in the log below is used in p2p_high_latency_test.py test
peer_dlog(c, "Network latency is ${lat}ms, ${num} blocks discrepancy by network latency, ${tot_num} blocks discrepancy expected once message received",
("lat", network_latency_ns/1000000)("num", nblk_behind_by_net_latency)("tot_num", nblk_combined_latency));
Expand All @@ -1813,8 +1813,8 @@ namespace eosio {
//-----------------------------

if (head_id == msg.head_id) {
peer_ilog( c, "handshake lib ${lib}, head ${head}, head id ${id}.. sync 0",
("lib", msg.last_irreversible_block_num)("head", msg.head_num)("id", msg.head_id.str().substr(8,16)) );
peer_ilog( c, "handshake lib ${lib}, head ${head}, head id ${id}.. sync 0, lib ${l}",
Copy link
Contributor

@greg7mdp greg7mdp Feb 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we factorize these 5 peer_ilog as in:

      auto log_handshake = [&](uint32_t sync) {
         peer_ilog( c, "handshake lib ${lib}, head ${head}, head id ${id}.. sync ${sync}, head ${h}, lib ${l}",
                    ("lib", msg.last_irreversible_block_num)("head", msg.head_num)("id", msg.head_id.str().substr(8,16))
                    ("sync", sync)("h", head)("l", lib_num) );
      };

      if (head_id == msg.head_id) {
         log_handshake(0);
         c->syncing = false;
         notice_message note;
         note.known_blocks.mode = none;
         note.known_trx.mode = catch_up;
         note.known_trx.pending = 0;
         c->enqueue( note );
         return;
      }
      if (head < msg.last_irreversible_block_num) {
         log_handshake(1);
         c->syncing = false;
         if (c->sent_handshake_count > 0) {
            c->send_handshake();
         }
         return;
      }
      if (lib_num > msg.head_num + nblk_combined_latency) {
         log_handshake(2);
         if (msg.generation > 1 || c->protocol_version > proto_base) {
            notice_message note;
            note.known_trx.pending = lib_num;
            note.known_trx.mode = last_irr_catch_up;
            note.known_blocks.mode = last_irr_catch_up;
            note.known_blocks.pending = head;
            c->enqueue( note );
         }
         c->syncing = true;
         return;
      }

      if (head + nblk_combined_latency < msg.head_num ) {
         log_handshake(3);
         c->syncing = false;
         verify_catchup(c, msg.head_num, msg.head_id);
         return;
      } else if(head >= msg.head_num + nblk_combined_latency) {
         log_handshake(4);
         ...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer not to as you lose line #.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fair enough! Although you could replace the lambda with a macro, as in:

#define log_handshake(sync) \
         peer_ilog( c, "handshake lib ${lib}, head ${head}, head id ${id}.. sync ${sync}, head ${h}, lib ${l}",\
                    ("lib", msg.last_irreversible_block_num)("head", msg.head_num)("id", msg.head_id.str().substr(8,16))\
                    ("sync", sync)("h", head)("l", lib_num) );

but maybe we should leave good enough alone :-).

("lib", msg.last_irreversible_block_num)("head", msg.head_num)("id", msg.head_id.str().substr(8,16))("l", lib_num) );
c->syncing = false;
notice_message note;
note.known_blocks.mode = none;
Expand All @@ -1823,18 +1823,20 @@ namespace eosio {
c->enqueue( note );
return;
}
if (head < peer_lib) {
peer_ilog( c, "handshake lib ${lib}, head ${head}, head id ${id}.. sync 1",
("lib", msg.last_irreversible_block_num)("head", msg.head_num)("id", msg.head_id.str().substr(8,16)) );
if (head < msg.last_irreversible_block_num) {
peer_ilog( c, "handshake lib ${lib}, head ${head}, head id ${id}.. sync 1, head ${h}, lib ${l}",
("lib", msg.last_irreversible_block_num)("head", msg.head_num)("id", msg.head_id.str().substr(8,16))
("h", head)("l", lib_num) );
c->syncing = false;
if (c->sent_handshake_count > 0) {
c->send_handshake();
}
return;
}
if (lib_num > msg.head_num + nblk_combined_latency) {
peer_ilog( c, "handshake lib ${lib}, head ${head}, head id ${id}.. sync 2",
("lib", msg.last_irreversible_block_num)("head", msg.head_num)("id", msg.head_id.str().substr(8,16)) );
peer_ilog( c, "handshake lib ${lib}, head ${head}, head id ${id}.. sync 2, head ${h}, lib ${l}",
("lib", msg.last_irreversible_block_num)("head", msg.head_num)("id", msg.head_id.str().substr(8,16))
("h", head)("l", lib_num) );
if (msg.generation > 1 || c->protocol_version > proto_base) {
notice_message note;
note.known_trx.pending = lib_num;
Expand All @@ -1848,14 +1850,16 @@ namespace eosio {
}

if (head + nblk_combined_latency < msg.head_num ) {
peer_ilog( c, "handshake lib ${lib}, head ${head}, head id ${id}.. sync 3",
("lib", msg.last_irreversible_block_num)("head", msg.head_num)("id", msg.head_id.str().substr(8,16)) );
peer_ilog( c, "handshake lib ${lib}, head ${head}, head id ${id}.. sync 3, head ${h}, lib ${l}",
("lib", msg.last_irreversible_block_num)("head", msg.head_num)("id", msg.head_id.str().substr(8,16))
("h", head)("l", lib_num) );
c->syncing = false;
verify_catchup(c, msg.head_num, msg.head_id);
return;
} else if(head >= msg.head_num + nblk_combined_latency) {
peer_ilog( c, "handshake lib ${lib}, head ${head}, head id ${id}.. sync 4",
("lib", msg.last_irreversible_block_num)("head", msg.head_num)("id", msg.head_id.str().substr(8,16)) );
peer_ilog( c, "handshake lib ${lib}, head ${head}, head id ${id}.. sync 4, head ${h}, lib ${l}",
("lib", msg.last_irreversible_block_num)("head", msg.head_num)("id", msg.head_id.str().substr(8,16))
("h", head)("l", lib_num) );
if (msg.generation > 1 || c->protocol_version > proto_base) {
notice_message note;
note.known_trx.mode = none;
Expand Down