diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index f1be989a1e1..e115b124fd4 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -160,7 +160,8 @@ namespace eosio { void sync_reset_lib_num( const connection_ptr& conn ); void sync_reassign_fetch( const connection_ptr& c, go_away_reason reason ); void rejected_block( const connection_ptr& c, uint32_t blk_num ); - void sync_recv_block( const connection_ptr& c, const block_id_type& blk_id, uint32_t blk_num ); + void sync_recv_block( const connection_ptr& c, const block_id_type& blk_id, uint32_t blk_num, bool blk_applied ); + void sync_update_expected( const connection_ptr& c, const block_id_type& blk_id, uint32_t blk_num, bool blk_applied ); void recv_handshake( const connection_ptr& c, const handshake_message& msg ); void sync_recv_notice( const connection_ptr& c, const notice_message& msg ); }; @@ -1739,20 +1740,12 @@ namespace eosio { } // called from connection strand - void sync_manager::sync_recv_block(const connection_ptr& c, const block_id_type& blk_id, uint32_t blk_num) { - fc_dlog( logger, "got block ${bn} from ${p}", ("bn", blk_num)( "p", c->peer_name() ) ); - if( app().is_quiting() ) { - c->close( false, true ); - return; - } - c->consecutive_rejected_blocks = 0; + void sync_manager::sync_update_expected( const connection_ptr& c, const block_id_type& blk_id, uint32_t blk_num, bool blk_applied ) { std::unique_lock g_sync( sync_mtx ); - stages state = sync_state; - fc_dlog( logger, "state ${s}", ("s", stage_str( state )) ); - if( state == lib_catchup ) { + if( blk_num <= sync_last_requested_num ) { fc_dlog( logger, "sync_last_requested_num: ${r}, sync_next_expected_num: ${e}, sync_known_lib_num: ${k}, sync_req_span: ${s}", ("r", sync_last_requested_num)("e", sync_next_expected_num)("k", sync_known_lib_num)("s", sync_req_span) ); - if (blk_num != sync_next_expected_num) { + if (blk_num != sync_next_expected_num && !blk_applied) { auto sync_next_expected = sync_next_expected_num; g_sync.unlock(); fc_dlog( logger, "expected block ${ne} but got ${bn}, from connection: ${p}", @@ -1761,6 +1754,20 @@ namespace eosio { } sync_next_expected_num = blk_num + 1; } + } + + // called from connection strand + void sync_manager::sync_recv_block(const connection_ptr& c, const block_id_type& blk_id, uint32_t blk_num, bool blk_applied) { + fc_dlog( logger, "got block ${bn} from ${p}", ("bn", blk_num)( "p", c->peer_name() ) ); + if( app().is_quiting() ) { + c->close( false, true ); + return; + } + c->consecutive_rejected_blocks = 0; + sync_update_expected( c, blk_id, blk_num, blk_applied ); + std::unique_lock g_sync( sync_mtx ); + stages state = sync_state; + fc_dlog( logger, "state ${s}", ("s", stage_str( state )) ); if( state == head_catchup ) { fc_dlog( logger, "sync_manager in head_catchup state" ); sync_source.reset(); @@ -2155,7 +2162,7 @@ namespace eosio { connection_ptr c = shared_from_this(); - if( consecutive_immediate_connection_close > def_max_consecutive_immediate_connection_close ) { + if( consecutive_immediate_connection_close > def_max_consecutive_immediate_connection_close || no_retry == benign_other ) { auto connector_period_us = std::chrono::duration_cast( my_impl->connector_period ); std::lock_guard g( c->conn_mtx ); if( last_close == fc::time_point() || last_close > fc::time_point::now() - fc::microseconds( connector_period_us.count() ) ) { @@ -2421,8 +2428,7 @@ namespace eosio { if( my_impl->dispatcher->have_block( blk_id ) ) { fc_dlog( logger, "canceling wait on ${p}, already received block ${num}, id ${id}...", ("p", peer_name())("num", blk_num)("id", blk_id.str().substr(8,16)) ); - if( my_impl->sync_master->syncing_with_peer() ) - my_impl->sync_master->sync_recv_block( shared_from_this(), blk_id, blk_num ); + my_impl->sync_master->sync_recv_block( shared_from_this(), blk_id, blk_num, false ); cancel_wait(); pending_message_buffer.advance_read_ptr( message_length ); @@ -2650,6 +2656,7 @@ namespace eosio { c->enqueue( go_away_message( forked ) ); } else if( unknown_block ) { peer_ilog( c, "Peer asked for unknown block, sending: benign_other go away" ); + c->no_retry = benign_other; c->enqueue( go_away_message( benign_other ) ); } } ); @@ -2914,8 +2921,7 @@ namespace eosio { c->strand.post( [sync_master = my_impl->sync_master.get(), dispatcher = my_impl->dispatcher.get(), c, blk_id, blk_num]() { dispatcher->add_peer_block( blk_id, c->connection_id ); - if( my_impl->sync_master->syncing_with_peer() ) - sync_master->sync_recv_block( c, blk_id, blk_num ); + sync_master->sync_recv_block( c, blk_id, blk_num, false ); }); return; } @@ -2958,7 +2964,7 @@ namespace eosio { }); c->strand.post( [sync_master = my_impl->sync_master.get(), dispatcher = my_impl->dispatcher.get(), c, blk_id, blk_num]() { dispatcher->recv_block( c, blk_id, blk_num ); - sync_master->sync_recv_block( c, blk_id, blk_num ); + sync_master->sync_recv_block( c, blk_id, blk_num, true ); }); } else { c->strand.post( [sync_master = my_impl->sync_master.get(), dispatcher = my_impl->dispatcher.get(), c, blk_id, blk_num]() {