Skip to content

Commit 740ec2e

Browse files
committed
GH-1224 Do not close connection on block_nack block_notice if blocks not available
1 parent cac0079 commit 740ec2e

File tree

1 file changed

+34
-19
lines changed

1 file changed

+34
-19
lines changed

plugins/net_plugin/net_plugin.cpp

+34-19
Original file line numberDiff line numberDiff line change
@@ -608,20 +608,33 @@ namespace eosio {
608608

609609
constexpr uint16_t net_version_max = proto_block_nack;
610610

611-
/**
612-
* Index by start_block_num
613-
*/
614611
struct peer_sync_state {
615-
explicit peer_sync_state(uint32_t start = 0, uint32_t end = 0, uint32_t last_acted = 0)
616-
:start_block( start ), end_block( end ), last( last_acted ),
617-
start_time(time_point::now())
612+
enum class sync_t {
613+
peer_sync, // LIB or head catchup, syncing request_message:catch_up
614+
block_nack // sync due to block nack (block_notice_message) request_message:normal
615+
};
616+
peer_sync_state(uint32_t start, uint32_t end, uint32_t last_acted, sync_t sync_type)
617+
:start_block( start ), end_block( end ), last( last_acted ), sync_type( sync_type )
618618
{}
619+
620+
bool valid() const;
621+
619622
uint32_t start_block;
620623
uint32_t end_block;
621624
uint32_t last; ///< last sent or received
622-
time_point start_time; ///< time request made or received
625+
sync_t sync_type;
623626
};
624627

628+
bool peer_sync_state::valid() const {
629+
bool valid = start_block > 0 && end_block >= start_block && last >= start_block && last <= end_block;
630+
if (sync_type == sync_t::block_nack && valid) {
631+
// block nack should only be used for "current" blocks, limit size to something reasonable
632+
const auto size = end_block - start_block;
633+
valid = size < 100;
634+
}
635+
return valid;
636+
}
637+
625638
// thread safe
626639
class queued_buffer : boost::noncopyable {
627640
public:
@@ -1010,7 +1023,7 @@ namespace eosio {
10101023

10111024
void blk_send_branch( const block_id_type& msg_head_id );
10121025
void blk_send_branch_from_nack_request( const block_id_type& msg_head_id, const block_id_type& req_id );
1013-
void blk_send_branch( uint32_t msg_head_num, uint32_t fork_db_root_num, uint32_t head_num );
1026+
void blk_send_branch(uint32_t msg_head_num, uint32_t fork_db_root_num, uint32_t head_num, peer_sync_state::sync_t sync_type);
10141027

10151028
void enqueue( const net_message& msg );
10161029
size_t enqueue_block( const std::vector<char>& sb, uint32_t block_num, queued_buffer::queue_t queue );
@@ -1516,7 +1529,7 @@ namespace eosio {
15161529

15171530
auto msg_head_num = block_header::num_from_id(msg_head_id);
15181531
if (msg_head_num == 0) {
1519-
blk_send_branch( msg_head_num, fork_db_root_num, head_num );
1532+
blk_send_branch( msg_head_num, fork_db_root_num, head_num, peer_sync_state::sync_t::peer_sync );
15201533
return;
15211534
}
15221535

@@ -1529,7 +1542,7 @@ namespace eosio {
15291542
// if peer on fork, start at their last fork_db_root_num, otherwise we can start at msg_head+1
15301543
if (on_fork)
15311544
msg_head_num = 0;
1532-
blk_send_branch( msg_head_num, fork_db_root_num, head_num );
1545+
blk_send_branch( msg_head_num, fork_db_root_num, head_num, peer_sync_state::sync_t::peer_sync );
15331546
}
15341547
}
15351548

@@ -1542,28 +1555,30 @@ namespace eosio {
15421555
// a more complicated better approach would be to find where the fork branches and send from there, for now use lib
15431556
uint32_t fork_db_root_num = my_impl->get_fork_db_root_num();
15441557
// --fork_db_root_num since blk_send_branch adds one to the request, and we want to start at fork_db_root_num
1545-
blk_send_branch( --fork_db_root_num, 0, head_num);
1558+
blk_send_branch( --fork_db_root_num, 0, head_num, peer_sync_state::sync_t::block_nack);
15461559
} else {
15471560
auto msg_req_num = block_header::num_from_id(req_id);
15481561
// --msg_req_num since blk_send_branch adds one to the request, and we need to start at msg_req_num
1549-
blk_send_branch( --msg_req_num, 0, head_num );
1562+
blk_send_branch( --msg_req_num, 0, head_num, peer_sync_state::sync_t::block_nack );
15501563
}
15511564
}
15521565

15531566
// called from connection strand
1554-
void connection::blk_send_branch( uint32_t msg_head_num, uint32_t fork_db_root_num, uint32_t head_num ) {
1567+
void connection::blk_send_branch( uint32_t msg_head_num, uint32_t fork_db_root_num, uint32_t head_num, peer_sync_state::sync_t sync_type) {
15551568
if( !peer_requested ) {
15561569
auto last = msg_head_num != 0 ? msg_head_num : fork_db_root_num;
1557-
peer_requested = peer_sync_state( last+1, head_num, last );
1570+
peer_requested = peer_sync_state( last+1, head_num, last, sync_type );
15581571
} else {
15591572
auto last = msg_head_num != 0 ? msg_head_num : std::min( peer_requested->last, fork_db_root_num );
15601573
uint32_t end = std::max( peer_requested->end_block, head_num );
15611574
if (peer_requested->start_block <= last+1 && peer_requested->end_block >= end)
15621575
return; // nothing to do, send in progress
1563-
peer_requested = peer_sync_state( last+1, end, last );
1576+
peer_requested = peer_sync_state( last+1, end, last, sync_type );
15641577
}
1565-
if( peer_requested->start_block <= peer_requested->end_block ) {
1566-
peer_ilog( this, "enqueue ${s} - ${e}", ("s", peer_requested->start_block)("e", peer_requested->end_block) );
1578+
if( peer_requested->valid() ) {
1579+
peer_ilog( this, "enqueue ${t} ${s} - ${e}",
1580+
("t", sync_type == peer_sync_state::sync_t::peer_sync ? "peer" : "block")
1581+
("s", peer_requested->start_block)("e", peer_requested->end_block) );
15671582
enqueue_sync_block();
15681583
} else {
15691584
peer_ilog( this, "nothing to enqueue" );
@@ -1778,7 +1793,7 @@ namespace eosio {
17781793
peer_dlog( this, "completing enqueue_sync_block ${num}", ("num", num) );
17791794
}
17801795
} else {
1781-
peer_ilog( this, "enqueue sync, unable to fetch block ${num}, sending benign_other go away", ("num", num) );
1796+
peer_ilog( this, "enqueue peer sync, unable to fetch block ${num}, sending benign_other go away", ("num", num) );
17821797
peer_requested.reset(); // unable to provide requested blocks
17831798
block_sync_send_start = 0ns;
17841799
block_sync_frame_bytes_sent = 0;
@@ -3813,7 +3828,7 @@ namespace eosio {
38133828
peer_requested->end_block = std::max(msg.end_block, peer_requested->end_block);
38143829
}
38153830
else {
3816-
peer_requested = peer_sync_state( msg.start_block, msg.end_block, msg.start_block-1);
3831+
peer_requested = peer_sync_state(msg.start_block, msg.end_block, msg.start_block-1, peer_sync_state::sync_t::peer_sync);
38173832
}
38183833
enqueue_sync_block();
38193834
}

0 commit comments

Comments
 (0)